我有两张表user
和pair
。我想获得每个(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;
答案 0 :(得分:0)
如果数据库能够按顺序遍历行,则可以加快GROUP BY name
操作,而无需对表进行排序。
这可以通过name
列上的索引来完成(另一列将其设为covering index,这只会有所帮助):
CREATE INDEX user_name_id_index ON user(name, id);
该查询按pair
,id
和a
值查找b
行;这些查找可以通过这些列的索引来加速:
CREATE INDEX pair_id_a_b_index ON pair(id, a, b);
为了帮助查询优化器在选择索引时做出更好的决策,请运行ANALYZE。
查询优化器不断改进;如果可能,请获取newest SQLite version。
要检查查询的执行方式,请查看EXPLAIIN QUERY PLAN命令的输出。