2013-08-01 27 views
19

Mam dwa SQLite tabele tak:Jak wybrać pierwsze N ​​wierszy każdej grupy?

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 

chcę zrobić kwerendę wybierającą, która zwróci pierwszy N (np dwa) wiersze dla każdego AuthorId, zamawianie według tytułu ("Wybierz dwie pierwsze książki każdy autor "). Wyjście

Próbka:

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 

Jak mogę zbudować tej kwerendy?

(Tak, znalazłem podobny temat i wiem, jak zwrócić tylko jeden wiersz (pierwszy lub górny). Problem dotyczy dwóch).

+0

Ktoś miał podobny problem tutaj http://stackoverflow.com/questions/9518900/how-to-find-teams-with-sql-command –

+0

proszę zobaczyć [ "Pytania powinny zawierać«znaczniki»w ich tytułów? "] (http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles), gdzie konsensus brzmi" nie, nie powinien "! –

Odpowiedz

12

Można to zrobić za pomocą liczenia skorelowane podzapytanie:

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; 

Dla małej bazy danych powinno być w porządku. Jeśli utworzysz indeks złożony na Book(AuthorId, BookId), to pomoże to zapytaniu.

13

Istnieje alternatywny wariant:

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

Podobała mi się ta odpowiedź lepiej dla mojego konkretnego przypadku, ale MySQL nie obsługiwał "limitu" wewnątrz podzapytania "w", więc musiałem iść z innym rozwiązaniem ... :(i tak przegłosowałem :) – msb

0

Tutaj jesteś. Może być za późno, ale właśnie zobaczyłem post. Możesz zmienić wartość < = 2, aby dopasować ją do n, której potrzebujesz.

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

To nie kwalifikuje się 'jako odpowiedź SQLite :-) – user1735003

Powiązane problemy