2013-08-01 30 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 

我想打一個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 

如何建立這個查詢?

(是的,我找到了一個類似的話題,我知道如何返回只有一行(第一或頂部)。

+0

有人在這裏遇到過類似問題http://stackoverflow.com/questions/9518900/how-to-find-teams-with-sql-command –

+0

請參見[56,「問題包括‘標籤中的’他們標題?「](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不支持在子查詢中的「限制」,所以我不得不與其他解決方案一起去...... :(upvoted無論如何:) – msb

0

在這裏你去。可能爲時已晚,但我剛剛看到帖子。您可以更改< = 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 
+2

這不符合'限定'作爲SQLite的答案:-) – user1735003