2014-11-24 55 views
1

我有兩個表userpair。我想獲得每個user.name重複對(a, b)的數量。SQLite子查詢:「IN」外部查詢的結果

用戶

name | id 
------------- 
"Alice" | 0 
"Bob" | 1 
"Alice" | 2 

id | a | b 
----------- 
0 | 0 | 1 
0 | 1 | 3 
1 | 0 | 1 
2 | 1 | 3 

在上面的例子中,結果應該是:

name | id | c 
------------------- 
"Alice" | 0,2 | 1 
"Bob" | 1 | 0 

當僅存在一個id爲EAC^h用戶,我可以這樣做:

SELECT name, id, (
    SELECT COUNT(*) FROM pair JOIN pair AS p USING (id, a, b) 
    WHERE id = user.id AND pair.rowid < p.rowid 
) AS c FROM user; 

當有多個id S,我可以從下面的查詢得到正確的結果,但它是相當緩慢的,當有更多的列以及更多的子查詢。

SELECT name, GROUP_CONCAT(id), (
    WITH t AS (SELECT id FROM user AS u WHERE name = user.name) 
    SELECT COUNT(*) FROM pair JOIN pair AS p USING (a, b) 
    WHERE pair.id IN t AND p.id IN t AND pair.rowid < p.rowid 
) AS c FROM user GROUP BY name; 

我想知道,是有這樣的簡單有效的方法,如改變從pair.id = user.idWHERE子句pair.id IN <<the user.id list>>

/* This will not work! "Error: no such table: user.id" */ 
SELECT name, GROUP_CONCAT(id), (
    SELECT COUNT(*) FROM pair JOIN pair AS p USING (a, b) 
    WHERE pair.id IN user.id AND p.id IN user.id AND pair.rowid < p.rowid 
) AS c FROM user GROUP BY name; 
+0

你有沒有索引? – 2014-11-24 11:54:54

+0

@CL。如果我有索引,會更容易嗎? – 2014-11-24 15:21:36

回答

0

GROUP BY name操作可以加快如果數據庫能夠經過行才能,而不必對錶進行排序。 這可以用在name列的索引來完成(其它列使這是一個covering index,只多一點幫助):

CREATE INDEX user_name_id_index ON user(name, id); 

查詢通過查找pair行的idab值;這些查詢可以加快對這些列的索引:

CREATE INDEX pair_id_a_b_index ON pair(id, a, b); 

爲了幫助選擇索引時,運行ANALYZE查詢優化器做出更好的決策。

查詢優化器不斷得到改進;如果可能,請獲得newest SQLite version

要檢查查詢的執行方式,請查看EXPLAIIN QUERY PLAN命令的輸出。

+0

這意味着我可以通過簡單地在我的表上創建索引來加速原始查詢。但是有沒有像子查詢中的WHERE pair.id IN << user.id list >>?或者我不能那樣做? – 2014-11-25 03:41:04

+0

有些東西像'WHERE pair.id IN << user.id list >>';在你的查詢中,user.id列表被稱爲't'。 – 2014-11-25 07:42:05

+0

不,我的意思是我可以在外部查詢中使用''user.id list''(就像我在單個id情況下做的那樣,直接使用'WHERE id = user.id'),而不用重新查詢它作爲一個表't'? – 2014-11-26 05:05:24