compare records within same table - sql

I have Student_Table with following structure.
Student_Note Table
student_id seq_num note
11212 1 firstnote
11212 2 secondNote
11212 3 thirdNote
21232 1 secondstudentnote1
21232 2 secondstudentnote2
so on
I want to get latest note (which has largest seq_num) for a particilar student.
I have tried following query
select tn.note from Student_Note tn JOIN Student_Note tn1
ON (tn.student_id =tn1.student_id AND tn.seq_num < tn1.seq_num)
where tn.student_id=11212
it is giving more than one row. How to achieve aforementioned scenario ?
I forgot mention that I am using above query as subquery . As per sybase TOP clause will not work in subquery.
P.S. I am using sybase.

OK - changed as apparently cannot use TOP.........
select tn.note from Student_Note tn
where tn.student_id=11212
and tn.seq_num = (SELECT MAX(seq_num) from Student_Note WHERE Student_Note.Student_Id = tn.Student_Id)

Please try this
select substring(max(str(seq_num,10,'0') + note),11,len(note))
from Student_Note
where student_id=11212

Related

How to make this 2 step query solution better

Query is made in MS Access :
I show now a simplified example of my problem.
I have one table Members
Name/age/nickname
- Tom/12/wolf
- Chris/11/ranger
- Phil/14/H-man
- Chris/16/walker
- Chris/18/Mo
Goal: How many times a name occurs , but only count when the nickname had an "a" in it.
I needed 2 queries;
Step1:
SELECT Members.Name, Members.Age, Members.Nickname
FROM Members
WHERE (((Members.Nickname) Like "*A*"));
Step2:
SELECT Step1.Name, Count(Step1.Age) AS AantalVanAge
FROM Step1
GROUP BY Step1.Name;
Result
- Chris 2
- Phil 1
You can achieve this in a single query using:
select t.name, count(*) as AantalVanAge
from members t
where t.nickname like "*A*"
group by t.name
Use your 1st query as a subquery in the 2nd step:
SELECT t.Name, Count(t.Age) AS AantalVanAge
FROM (
SELECT Name, Age
FROM Members
WHERE Nickname Like "*A*"
) AS t
GROUP BY t.Name;

To pair up records in oracle sql

This is my sql:
when executed, it said
00000 - "missing keyword" on the position of "CROSS APPLY".
I'm just trying to pair up some records (in one day =20160720) with same TICKET_ID in the table and return their T_TIME and T_LOCATION.
select a.T_TIME, b.T_TIME, a.T_LOCATION, b.T_LOCATION
FROM TABLE a
CROSS APPLY
(select * from TABLE b where a.TICKET_ID = b.TICKET_ID having count(TICKET_ID) > 1) b
where (a.T_DATE=20160720);
Is the problem caused by using CROSS APPLY?
Ok, here is the problem I originally want to solve :)
The table looks like this:
T_TIME |T_LOCATION | TICKET_ID|T_DATE
20160720091032| ---0103| 1A268F|20160720
20160720095842| ---0115| 63T37H|20160720
20160720133408| ---0124| 1A268F|20160720
20160721152400| ---0116| 598I3R|20160721
20160720125844| ---0147| 63T37H|20160720
I want to pair up the records with same TICKET_ID. 2 records share one same TICKET_ID. And I want the output like:
20160720091032|20160720133408|0103|0124|
20160720095842|20160720125844|0115|0147|
The table is very large like for T_DATE=20160720 there will be 200000 records in total.
One way of doing it would be:
select a.ticket_id, a.t_time, b.t_time, a.t_location, b.t_location
from the_table a
join the_table b on a.ticket_id = b.ticket_id and a.t_time < b.t_time
where a.t_date = 20160720;
The join condition and a.t_time < b.t_time ensure that the "other" version of a pair isn't in the result e.g. you only get (0103, 0124) but not (0124, 0103).

Only a single result allowed for a SELECT that is part of an expression

I have the following SQL statement. It's throws the following error: "Only a single result allowed for a SELECT that is part of an expression". The goal of my sql statement is to get the name of the employee who made the 'cheapest' bribe.
The part between the brackets return the employee_id and the money it costs a day (of the relative cheapest bribe). These are two results while I only want the employee_id. So I just want to use the MIN part to get the right employee_id. How can I do this?
SELECT Voornaam, Achternaam
FROM Medewerker m JOIN
(
SELECT Medewerker_id
FROM Steekpenning
ORDER BY -1*Bedrag/(julianday(Begindatum) - julianday(Einddatum))
limit 1
) s
on m.Medewerker_id = s.Medewerker_id;
EDITED the answer. How can I expand this query to only show the bribes started this month? I think I need to use something like this? (julianday(Begindatum) - julianday('now')) > 31 but where?
Regards.
Cas
I think the following will work in SQLite:
select Firstname, Surname
from Employee e join
(select employee_id
from bribe
order by -1*Amount/(julianday(Startdate) - julianday(Enddate))
limit 1
) b
on e.employee_id = b.employee_id;

How to Avoid Duplicate ID's In Access SQL

I have a problem that I hope you can help me.
I have the next query on Access SQL.
SELECT
ID_PLAN_ACCION, ID_SEGUIMIENTO,
Max(FECHA_SEGUIMIENTO) AS MAX_FECHA
FROM
SEGUIMIENTOS
WHERE
(((ID_PLAN_ACCION) = [CODPA]))
GROUP BY
ID_PLAN_ACCION, ID_SEGUIMIENTO;
And it returns this information:
ID_PLAN_ACCION ID_SEGUIMIENTO MAX_FECHA
-----------------------------------------------
A1-01 1 16/01/2014
A1-01 2 30/01/2014
But I really need that it throws off this:
ID_PLAN_ACCION ID_SEGUIMIENTO MAX_FECHA
----------------------------------------------
A1-01 2 30/01/2014
As you can see I only need the record that has the most recently date, not all the records
The GROUP BY doesn't work.
Please can you tell me what can I do? I am new on all this.
Thank you so much!!
PD: Sorry for my english, I'm learning
This will produce the results you want:
SELECT ID_PLAN_ACCION, max(ID_SEGUIMIENTO) as ID_SEGUIMIENTO, Max(FECHA_SEGUIMIENTO) AS MAX_FECHA
FROM SEGUIMIENTOS
WHERE ID_PLAN_ACCION = [CODPA]
GROUP BY ID_PLAN_ACCION;
I removed id_sequiimiento from the group by and added an aggregation function to get the max value. If the ids increase along with the date, this will work.
Another way to approach this query, though, is to use top and order by:
SELECT top 1 ID_PLAN_ACCION, ID_SEGUIMIENTO, FECHA_SEGUIMIENTO
FROM SEGUIMIENTOS
WHERE ID_PLAN_ACCION = [CODPA]
ORDER BY FECHA_SEGUIMIENTO desc;
This works because you are only returning one row.
EDIT:
If you have more codes, that you are looking at, you need a more complicated query. Here is an approach using where/not exists:
SELECT ID_PLAN_ACCION, ID_SEGUIMIENTO, FECHA_SEGUIMIENTO
FROM SEGUIMIENTOS s
WHERE not exists (select 1
from SEGUIMIENTOS s2
where s.ID_PLAN_ACCION = s2.ID_PLAN_ACCION and
s2.FECHA_SEGUIMIENTO > s.FECHA_SEGUIMIENTO
)
ORDER BY FECHA_SEGUIMIENTO desc;
You can read this as: "Get me all rows from SEGUIMIENTOS where there is no other row with the same ID_PLAN_ACCION that has a larger date". Is is another way of saying that the original row has the maximum date.

How to combine this query

In the query
cr is customers,
chh? ise customer_pays,
cari_kod is customer code,
cari_unvan1 is customer name
cha_tarihi is date of pay,
cha_meblag is pay amount
The purpose of query, the get the specisified list of customers and their last date for pay and amount of money...
Actually my manager needs more details but the query is very slow and that is why im using only 3 subquery.
The question is how to combine them ?
I have researched about Cte and "with clause" and "subquery in "where " but without luck.
Can anybody have a proposal.
Operating system is win2003 and sql server version is mssql 2005.
Regards
select cr.cari_kod,cr.cari_unvan1, cr.cari_temsilci_kodu,
(select top 1
chh1.cha_tarihi
from dbo.CARI_HESAP_HAREKETLERI chh1 where chh1.cha_kod=cr.cari_kod order by chh1.cha_RECno) as sontar,
(select top 1
chh2.cha_meblag
from dbo.CARI_HESAP_HAREKETLERI chh2 where chh2.cha_kod=cr.cari_kod order by chh2.cha_RECno) as sontutar
from dbo.CARI_HESAPLAR cr
where (select top 1
chh3.cha_tarihi
from dbo.CARI_HESAP_HAREKETLERI chh3 where chh3.cha_kod=cr.cari_kod order by chh3.cha_RECno) >'20130314'
and
cr.cari_bolge_kodu='322'
or
cr.cari_bolge_kodu='324'
order by cr.cari_kod
You will probably speed up the query by changing your last where clause to:
where (select top 1 chh3.cha_tarihi
from dbo.CARI_HESAP_HAREKETLERI chh3 where chh3.cha_kod=cr.cari_kod
order by chh3.cha_RECno
) >'20130314' and
cr.cari_bolge_kodu in ('322', '324')
order by cr.cari_kod
Assuming that you want both the date condition met and one of the two codes. Your original logic is the (date and code = 322) OR (code = 324).
The overall query can be improved by finding the record in the chh table and then just using that. For this, you want to use the window function row_number(). I think this is the query that you want:
select cari_kod, cari_unvan1, cari_temsilci_kodu,
cha_tarihi, cha_meblag
from (select cr.*, chh.*,
ROW_NUMBER() over (partition by chh.cha_kod order by chh.cha_recno) as seqnum
from dbo.CARI_HESAPLAR cr join
dbo.CARI_HESAP_HAREKETLERI chh
on chh.cha_kod=cr.cari_kod
where cr.cari_bolge_kodu in ('322', '324')
) t
where chh3.cha_tarihi > '20130314' and seqnum = 1
order by cr.cari_kod;
This version assumes the revised logic date/code logic.
The inner subquery select might generate an error if there are two columns with the same name in both tables. If so, then just list the columns instead of using *.