2013-08-01 9 views
19

Ich habe zwei SQLite Tabellen wie folgt aus:Wie wähle ich die ersten N Zeilen jeder Gruppe?

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 

Ich möchte eine SELECT-Abfrage machen, die die erste N (zB zwei) Reihen für jeden authorid zurückkehren, nach Titel Bestellung ("Wählen Sie die ersten beiden Bücher von jeder Autor ").

Beispielausgabe:

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 

Wie kann ich diese Abfrage zu erstellen?

(Ja, ich fand ein ähnliches Thema, und ich weiß, wie man nur eine Zeile (zuerst oder oben) zurückgibt. Das Problem ist mit den beiden).

+0

Jemand hatte ein ähnliches Problem hier http://stackoverflow.com/questions/9518900/how-to-find-teams-with-sql-command –

+0

Bitte sehen [ "Should Fragen umfassen‚Tags‘in ihrem Titel? "] (http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-the-titles), wo der Konsens ist" Nein, sollten sie nicht "! –

Antwort

12

Sie können das Zählen tun eine korrelierte Unterabfrage mit:

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; 

Für eine kleine Datenbank dies sollte in Ordnung sein. Wenn Sie einen zusammengesetzten Index für Book(AuthorId, BookId) erstellen, hilft das der Abfrage.

13

Es gibt alternative Variante:

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

Ich mochte diese Antwort besser für meinen speziellen Fall, aber MySQL unterstützt "Limit" innerhalb "in" Unterabfrage nicht, also musste ich mit der anderen Lösung gehen ... :(upvoted sowieso :) – msb

0

Hier gehen Sie. Könnte zu spät sein, aber ich habe gerade die Post gesehen. Sie können den Wert < = 2 ändern, damit er dem n entspricht, den Sie benötigen.

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

Dies ist nicht qualifiziert 'als SQLite Antwort :-) – user1735003