SQLite子查询:“IN”外部查询的结果

时间:2014-11-24 09:14:14

标签: sqlite subquery

我有两张表userpair。我想获得每个(a, b)的重复对user.name的数量。

用户

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,我可以这样做:

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时,我可以从下面的查询中获得正确的结果,但是当有更多的行和更多的子查询时它会非常慢。

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;

我想知道有一种简单而有效的方法,例如将WHERE条款从pair.id = user.id更改为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;

1 个答案:

答案 0 :(得分:0)

如果数据库能够按顺序遍历行,则可以加快GROUP BY name操作,而无需对表进行排序。 这可以通过name列上的索引来完成(另一列将其设为covering index,这只会有所帮助):

CREATE INDEX user_name_id_index ON user(name, id);

该查询按pairida值查找b行;这些查找可以通过这些列的索引来加速:

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

为了帮助查询优化器在选择索引时做出更好的决策,请运行ANALYZE

查询优化器不断改进;如果可能,请获取newest SQLite version

要检查查询的执行方式,请查看EXPLAIIN QUERY PLAN命令的输出。

相关问题