Select top year and term for each student - sql

I want to return each student final semester record from these tables.
Table: dbo.Stdetail
StID YearID TermID
2 1 1
3 1 1
3 2 1
3 2 2
3 3 1
3 3 2
4 1 1
4 1 2
5 1 1
5 1 2
Table: dbo.lastyear
StID YearID TermID
1 5 1
2 5 1
2 6 2
3 5 1
3 6 2
From these two tables I want to return final yearID and term ID.
Desired output:
StID yearID TermID
1 5 1
2 6 2
3 6 2
4 1 2
5 1 2

I think you want to union together dbo.Stdetail and dbo.lastyear and then apply use row_number() to identify the most last record for each student. Like this:
;with cte as (select *
, row_number() over (partition by StID order by YearID desc, TermID desc) rn
from (select StID, YearID, TermID from dbo.Stdetail
union
select StID, YearID, TermID from dbo.lastyear) x
)
select *
from cte
where rn = 1

Related

SQL Take Max and Include Non-Group By COLS

TABLE1
ID STUDENT SCORE TIME
A 1 9 1
A 1 8 2
B 1 0 1
B 1 10 2
B 1 7 3
C 2 5 1
C 2 1 2
C 2 0 3
D 3 1 1
E 3 0 1
D 3 4 2
D 3 4 3
E 3 9 2
F 4 6 1
G 4 6 1
WANT
ID STUDENT MAXSCORE TIME
A 1 9 1
B 1 10 2
B 1 7 3
C 2 5 1
C 2 1 2
C 2 0 3
D 3 1 1
E 3 9 2
D 3 4 3
F 4 6 1
I have TABLE1 and wish for WANT which does this:
for every STUDENT/TIME, select the row with the MAX(SCORE)
I try this::
select ID, STUDENT, MAX(SCORE) AS MAXSCORE, TIME
from TABLE1
group by STUDENT, TIME
But amn't able to include ID
First get the max score by student/time, then join back to the original table.
WITH dat
AS
(
SELECT student, time, MAX(score) AS max_score
FROM TABLE1
GROUP BY student, time
)
SELECT DISTINCT t.id, t.student, d.max_score, t.time
FROM TABLE1 t
INNER JOIN dat d
ON t.student = d.student AND t.time = d.time AND t.score = d.max_score;
If the RDBMS supports window functions, then
with cte as (
select id,
student,
score,
time,
row_number() over (partition by student, time order by score desc) as rn
from table1)
select id, student, score, time
from cte
where rn = 1;

Select commonly chosen desires collage by students after first 5 rows each group

With subquery I need to select after first five rows for each group of id_student and must common values of id_desireCollage between id_student.
More explain : select common collages for each student desires after his five chosen desires
ID
id_desireCollage
id_student
1
1
1
2
2
1
3
3
1
4
4
1
5
5
1
6
8
1
7
9
1
8
7
1
9
2
2
10
12
2
11
1
2
12
3
2
13
6
2
14
5
2
15
8
2
16
9
2
17
7
2
18
4
3
19
3
3
20
2
3
21
1
3
22
8
3
23
9
3
24
7
3
25
5
3
Something like
select id_desireCollage
from
(select *
from desires ds
where ds.id_desireCollage = desires.id_desireCollage)
group by (id_student)
having count(*) > 5
Expected result is:
id_desireCollage
7
9
Try the following:
select id_desireCollage
from
(
select d.*,
row_number() over (partition by id_student order by ID) as rn
from desires d
) T
where rn > 5
group by id_desireCollage
order by count(*) desc
fetch first 1 row with ties
If you don't want to use the row number function (as you commented), you may try the following - supposing there are no gaps in the ID column:
select id_desireCollage
from desires d
where id >=
(
select min(id)+5
from desires t
where t.id_student = d.id_student
)
group by id_desireCollage
order by count(*) desc
fetch first 1 row with ties
See demo
As suggested by #MatBailie, if you meant by common, that all students have selected the id_desireCollage value then you could use the following:
select id_desireCollage
from desires d
where id >=
(
select min(id)+5
from desires t
where t.id_student = d.id_student
)
group by id_desireCollage
having count(*)=
(
select count(distinct id_student)
from desires
)

DENSE_RANK () trick Oracle

I am confused about DENSE_Rank function
so I have a code like this
select ID, date
From TABLE1
order by date
so It executes like this
ID DATE
1 10/25/2016
1 10/23/2015
1 10/22/2014
2 10/11/2015
2 5/24/2014
2 5/21/2014
2 3/23/2013
3 10/21/2016
3 9/20/2015
my code is
select ID, Extract(MONTH FROM DATE), DENSE_RANK () OVER (PARTITION BY ID,Extract(MONTH FROM DATE order by DATE) rank
FROM TABLE
it shows
ID DATE RANK
1 10 1
1 10 2
1 10 3
2 10 1
2 5 1
2 5 2
2 3 1
3 10 1
3 9 2
but I would like to show like below
ID DATE RANK
1 10 1
1 10 1
1 10 1
2 10 1
2 5 2
2 5 2
2 3 3
3 10 1
3 9 2
how can I code to execute above
Thank you so much
You want to order by the month (in descending order) rather than partition by them:
SELECT ID,
Extract(MONTH FROM "DATE"),
DENSE_RANK () OVER ( PARTITION BY ID
ORDER BY Extract(MONTH FROM "DATE") DESC ) rank
FROM your_table

Select all rows if only one matches

I have two tables: FEATURE and FEATURE_DETAILS. Relation is one(FEATURE) to many(FEATURE_DETAILS).
feature_details_id | feature_id
1 1
1 2
1 4
2 1
2 2
2 4
2 5
3 1
3 5
How could I select all rows which contains e.g. 5?
feature_details_id | feature_id
2 1
2 2
2 4
2 5
3 1
3 5
first get the list of feature_deatails_id for which feature_id is 5, then pass the feature_deatails_id to FEATURE_DETAILS table to get the result
Try something like this
select *
from FEATURE_DETAILS
where feature_deatails_id in(
select feature_deatails_id from FEATURE_DETAILS where feature_id = 5)
or use Max()Over() Window function(preferred approach)
select * from
(
select max(case when feature_id = 5 then 1 else 0 end)over(partition by feature_deatails_id) as cnt,
feature_deatails_id,feature_id
from FEATURE_DETAILS
)s
Where cnt = 1
SELECT * FROM FEATURE_DETAILS WHERE feature_details_id IN (
SELECT feature_details_id from FEATURE_DETAILS WHERE feature_id=5
)

MySQL - Selecting records based on maximum secondary ID

Here's part of my table:
id team_id log_id
1 12 1
2 12 1
3 12 1
4 12 1
5 1 2
6 1 2
7 1 3
8 1 3
What query would produce this output (so only the records with the highest log_id values are returned that correspond to team_id)?
id team_id log_id
1 12 1
2 12 1
3 12 1
4 12 1
7 1 3
8 1 3
SELECT *
FROM mytable t
WHERE log_id = (SELECT MAX(log_id) FROM mytable WHERE team_id = t.team_id)
SELECT id, team_id, log_id
FROM table1 t2
JOIN (SELECT team_id, MAX(log_id) max_log_id
FROM table1
GROUP BY team_id) t2 ON t1.team_id = t2.team_id
AND t1.log_id = t2.max_log_id