2013-08-01 30 views
19

Ho due tabelle SQLite come questo:Come selezionare le prime N righe di ogni gruppo?

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 

Voglio fare una query SELECT che restituirà il primo N (ad esempio due) righe per ogni AuthorID, ordinando dal titolo ("Seleziona le prime due libri di ogni autore "). Uscita

Esempio:

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 

Come faccio a costruire questa ricerca?

(Sì, ho trovato un argomento simile, e so come restituire solo una riga (prima o cima) .Il problema è con i due).

+0

Qualcuno ha avuto un problema simile qui http://stackoverflow.com/questions/9518900/how-to-find-teams-with-sql-command –

+0

Si prega di consultare [ "domande dovrebbe includere‘tag’nel loro titoli? "] (http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles), dove il consenso è" no, non dovrebbero "! –

risposta

12

Si può fare il conteggio utilizzando una subquery correlata:

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; 

Per un piccolo database questo dovrebbe andare bene. Se crei un indice composito su Book(AuthorId, BookId), ciò aiuterà la query.

13

C'è variante alternativa:

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

Mi è piaciuta questa risposta meglio per il mio caso particolare, ma MySQL non supportava "limite" all'interno della sottoquery "in", quindi dovevo andare con l'altra soluzione ... :(upvoted comunque :) – msb

0

Qui si va. Potrebbe essere troppo tardi ma ho appena visto il post. È possibile modificare < = 2 in modo che corrisponda a n necessario.

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

Questo non 'qualifica 'come risposta SQLite :-) – user1735003

Problemi correlati