2013-08-01 5 views
19

У меня есть два SQLite таблицы, как это:Как выбрать первые N строк каждой группы?

AuthorId | AuthorName 
---------------------- 
1  | Alice 
2  | Bob 
3  | Carol 
...  | .... 


BookId | AuthorId | Title 
---------------------------------- 
1  | 1  | aaa1 
2  | 1  | aaa2 
3  | 1  | aaa3 
4  | 2  | ddd1 
5  | 2  | ddd2 
... | ...  | ... 
19  | 3  | fff1 
20  | 3  | fff2 
21  | 3  | fff3 
22  | 3  | fff4 

Я хочу, чтобы сделать запрос на выборку, которая будет возвращать первый N (например, два) строки для каждого AuthorID, заказав по заголовкам ("Выберите первые две книги каждый автор "). Выход

Пример:

BookId | AuthorId | AuthorName | Title 
------------------------------------------ 
1  | 1  | Alice | aaa1 
2  | 1  | Alice | aaa1 
4  | 2  | Bob  | ddd1 
5  | 2  | Bob  | ddd2 
19  | 3  | Carol | fff1 
20  | 3  | Carol | fff2 

Как я могу построить этот запрос?

(Да, я нашел аналогичную тему, и я знаю, как возвращать только одну строку (первую или верхнюю). Проблема в том, что эти два).

+0

Кто-то была аналогичная проблема здесь http://stackoverflow.com/questions/9518900/how-to-find-teams-with-sql-command –

+0

Пожалуйста, смотрите [ "Должны ли вопросы включают„метки“в их названия? »] (http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles), где консенсус« нет, они не должны »! –

ответ

12

Вы можете сделать подсчет с помощью связанного подзапроса:

SELECT b.BookId, a.AuthorId, a.AuthorName, b.Title 
FROM Author a join 
    Book b 
    on a.AuthorId = b.AuthorId 
where (select count(*) 
     from book b2 
     where b2.bookId <= b.BookId and b2.AuthorId = b.AuthorId 
    ) <= 2; 

Для небольшой базы данных, это должно быть хорошо. Если вы создадите составной индекс на Book(AuthorId, BookId), это поможет выполнить запрос.

13

Существует альтернативный вариант:

SELECT * FROM (
    SELECT * FROM BOOK, AUTHOR 
    WHERE BOOK.AUTHORID = AUTHOR.AUTHORID 
) T1 
WHERE T1.BOOKID IN (
    SELECT T2.BOOKID FROM BOOK T2 
    WHERE T2.AUTHORID = T1.AUTHORID 
    ORDER BY T2.BOOKTITLE 
    LIMIT 2 
) 
ORDER BY T1.BOOKTITLE 
+0

Мне понравился этот ответ лучше для моего конкретного случая, но MySQL не поддерживал «ограничение» внутри «в» подзапросе, поэтому мне пришлось пойти с другим решением ... :(в любом случае поддерживается :) – msb

0

Здесь вы идете. Может быть, слишком поздно, но я только что видел сообщение. Вы можете изменить < = 2, чтобы соответствовать нужде.

SELECT 
a.authorid, 
a.authorname, 
b.bookid, 
b.booktitle 
FROM author a 
JOIN book b ON b.authorid = b.authorid 
QUALIFY ROW_NUMBER() OVER (PARTITION BY a.authorid 
ORDER BY b.booktitle ASC) <=2 
+2

Это не «квалифицируется» 'как ответ SQLite :-) – user1735003

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