Как выбрать первые N строк каждой группы?
У меня есть две таблицы SQLite:
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
Я хочу сделать запрос SELECT, который вернет первые 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
Как я могу построить этот запрос?
(Да, я нашел подобную тему, и я знаю, как возвращать только одну строку (сначала или сверху). Проблема в том, что они оба).
Ответы
Ответ 1
Вы можете выполнить подсчет, используя коррелированный подзапрос:
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)
, то это поможет запросу.
Ответ 2
Существует альтернативный вариант:
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
Ответ 3
Здесь вы идете. Может быть, слишком поздно, но я только что видел сообщение. Вы можете изменить <= 2 в соответствии с потребностью n.
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