2015-01-23 4 views
2

Я пытаюсь выбрать топ 2 записей из результата таблицы базы данных, которая выглядит как этотвыбрать верхнюю п запись из каждой группы SQLite

SubjectId | StudentId | Levelid | total 
------------------------------------------ 
1  | 1   | 1  | 89 
1  | 2   | 1  | 77 
1  | 3   | 1  | 61 
2  | 4   | 1  | 60 
2  | 5   | 1  | 55 
2  | 6   | 1  | 45 

я попробовал этот запрос

SELECT rv.subjectid, 
     rv.total, 
     rv.Studentid, 
     rv.levelid 
    FROM ResultView rv 
     LEFT JOIN ResultView rv2 
       ON (rv.subjectid = rv2.subjectid 
    AND 
rv.total <= rv2.total) 
GROUP BY rv.subjectid, 
      rv.total, 
      rv.Studentid 
HAVING COUNT(*) <= 2 
order by rv.subjectid desc 

, но некоторые предметы, как где не хватает, я даже попробовал suggestiong FRM следующей ссылке

How to select the first N rows of each group?

но я получаю больше, чем два для каждого субъекта

что я делаю неправильно?

+0

'HAVING COUNT (*) <= 3' отфильтровывает любую группу с 3 или более строками. Но вы не хотите исключать целые группы, только любые строки за второй. – Andomar

+0

'HAVING COUNT (*) <= 3' был опечаткой, он был исправлен – Smith

+0

Если вы представляете пример желаемого вывода, проще дать ответ. – Johanneke

ответ

5

Вы можете использовать коррелировала подзапрос:

select * 
from ResultView rv1 
where SubjectId || '-' || StudentId || '-' || LevelId in 
     (
     select SubjectId || '-' || StudentId || '-' || LevelId 
     from ResultView rv2 
     where SubjectID = rv1.SubjectID 
     order by 
       total desc 
     limit 2 
     ) 

Этот запрос формирует один столбец первичного ключа с помощью конкатенации три столбца. Если у вас есть реальный первичный ключ (например, ResultViewID), вы можете заменить его на SubjectId || '-' || StudentId || '-' || LevelId.

Example at SQL Fiddle.

+0

спасибо за ответ, но я получаю другой результат. Пример, описанный выше, является упрощенной версией моей проблемы, возможно, поэтому. я опубликую более подробную версию. Таблица, которую я выбираю, на самом деле представляет собой представление, которое объединяет две таблицы по общему идентификатору. если я хочу выбрать этот результат, основанный на levelid, где я помещаю предложение 'where'? – Smith

2

Я надеюсь, что я понять ваш вопрос правильно. Дайте мне знать, если это правильно:

Я воссоздал таблицу:

CREATE TABLE stack (
     SubjectId INTEGER(10), 
     StudentId INTEGER(10), 
     Levelid INTEGER(10), 
     total INTEGER(10) 
     ) 
; 

Inserted дорожит

INSERT INTO stack VALUES 
     (1,1,1,89), 
     (1,2,1,77), 
     (1,3,1,61), 
     (2,4,1,60), 
     (2,5,1,55), 
     (2,6,1,45) 
; 

Если вы пытаетесь получить верхнюю группу по Levelid (по суммарному упорядочены поле , при условии, StudentID в качестве первичного ключа):

SELECT * 
FROM stack AS a 
WHERE a.StudentID IN (
     SELECT b.StudentID 
     FROM stack AS b 
     WHERE a.levelid = b.levelid 
     ORDER BY b.total DESC 
     LIMIT 2 
    ) 
; 

Вырабатывает этот результат:

SubjectId | StudentId | Levelid | total 
1   | 1   | 1  | 89 
1   | 2   | 1  | 77 

Пример сверху 2 по SubjectId, по заказу всего:

SELECT * 
FROM stack AS a 
WHERE a.StudentID IN (
     SELECT b.StudentID 
     FROM stack AS b 
     WHERE a.subjectID = b.subjectID 
     ORDER BY b.total DESC 
     LIMIT 2 
    ) 
; 

Результат:

SubjectId | StudentId | Levelid | total 
1   | 1   | 1  | 89 
1   | 2   | 1  | 77 
2   | 4   | 1  | 60 
2   | 5   | 1  | 55 

Я надеюсь, что это ответ, который вы искали.

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