2010-08-03 2 views
8

У меня есть ученик таблицы (id, имя, отдел, возраст, оценка). Я хочу найти младшего студента, у которого самый высокий (среди младших учеников) балл каждого отдела. В SQL Server я могу использовать следующий SQL.Получите верхнюю строку после заказа в Oracle Subquery

select * from student s1 
where s1.id in 
(select s2.id from student s2 
where s2.department = s1.department order by age asc, score desc top 1). 

Однако в Oracle, вы не можете использовать порядок пунктом в подзапрос и нет предела/сверху, как ключевое слово. Я должен присоединиться к таблице учеников два раза, чтобы запросить результат. В oracle я использую следующий SQL.

select s1.* from student s1, 
(select s2.department, s2.age, max(s2.score) as max_score from student s2, 
(select s3.department, min(s3.age) as min_age from student s3 group by s3.department) tmp1 where 
s2.department = tmp1.department and s2.age = tmp1.min_age group by s2.department, s2.age) tmp2 
where s1.department =tmp2.department and s1.age = tmp2.age and s1.score=tmp2.max_score 

У кого-нибудь есть идея упростить вышеуказанный SQL для оракула.

+1

В Oracle, вы можете * * использовать порядок пунктом в подзапроса. –

+0

Решение гораздо проще, без аналитических функций, см. Принятый ответ на мой вопрос: http://stackoverflow.com/questions/38180445/oracle-left-join-very-big-table-and-limit-the-joined -rows-to-one-with-the-large – Dany

ответ

24

попробовать это один

select * from 
    (SELECT id, name, department, age, score, 
    ROW_NUMBER() OVER (partition by department order by age desc, score asc) srlno 
    FROM student) 
where srlno = 1; 
+0

У меня был похожий сценарий, который, как считается, обрабатывал с использованием блока pl/sql, но ваше решение отлично работало !! – Rakesh

5

В дополнение к ответу Бхарат, это можно сделать с помощью ORDER BY в суб-запроса в Oracle (как точка из Джеффри Кемп):

SELECT * 
FROM student s1 
WHERE s1.id IN (SELECT id 
       FROM (SELECT id, ROWNUM AS rn 
         FROM  student s2 
         WHERE s1.department = s2.department 
         ORDER BY age ASC, score DESC) 
       WHERE rn = 1); 

Если вы используете этот метод, может возникнуть соблазн удалить подзапрос и просто использовать rownum = 1. Это приведет к неправильному результату, так как сортировка будет применяться после критериев (вы получите 1 строку, которая была отсортирована, а не одну строку из отсортированного набора).

+0

Вопрос фактически задает верхний ряд «каждого отдела». Вы не используете депарат для группировки результатов. Вероятно, этот ответ полезен для людей, которые ищут похожие вопросы к названию, не читая содержимое вопроса. Но я хочу указать на разницу для людей, сравнивающих решения (потому что они не получат одинаковых результатов). –

+0

@ Протрон: Хорошая добыча! Я обновил ответ. – Allan

1
select to_char(job_trigger_time,'mm-dd-yyyy') ,job_status from 
(select * from kdyer.job_instances ji INNER JOIN kdyer.job_param_values pm 
on((ji.job_id = pm.job_id) and (ji.job_spec_id = '10003') and (pm.param_value='21692')) 
order by ji.job_trigger_time desc) 
where rownum<'2' 
10

В дополнение к ответу Аллана, это работает отлично тоже:

select * 
from (SELECT * 
    FROM student 
    order by age asc, 
      score desc) 
where rownum = 1; 
+0

Это возвращает только верхний ряд результатов «все». Это может совпадать с заголовком вопроса. Но на самом деле вопрос задает верхний ряд «каждого отдела». Вот почему это проще, чем ответы Бхарата. –

+0

Это правда, Протрон, я действительно пропустил это различие, и ответил на более простой вопрос, который был на самом деле тем, что я искал сам, когда я искал googled и нашел эту нить. Поэтому я полагаю, что все ответы правильные и полезные, в зависимости от того, что читатель действительно ищет. Для моей цели ответ Аллана был самым полезным, а затем я уточнил его и отправил обратно. Для вашей цели ответ Бхарата является самым полезным. Все побеждают! (Хотя, я заметил, что Аллан отредактировал свой ответ из-за вашего запроса, но я оставлю свое, как есть, поскольку это прекрасный ответ для многих людей). – SurfingSanta

Смежные вопросы