【问题标题】:SQLite subquery: "IN" the result of the outer querySQLite 子查询:“IN”外部查询的结果
【发布时间】:2023-03-24 16:13:01
【问题描述】:

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

用户

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;

当有多个ids时,我可以从下面的查询中得到正确的结果,但是当有更多的行和更多的子查询时会很慢。

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 &lt;&lt;the user.id list&gt;&gt;

/* 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;

【问题讨论】:

  • 你有索引吗?
  • @CL。不会。如果我有索引会更容易吗?

标签: sqlite subquery


【解决方案1】:

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

CREATE INDEX user_name_id_index ON user(name, id);

查询通过idab 值查找pair 行;这些查找可以通过这些列上的索引来加速:

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

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

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

要检查您的查询是如何执行的,请查看EXPLAIIN QUERY PLAN 命令的输出。

【讨论】:

  • 这意味着我可以通过在我的表上创建索引来加速原始查询。但是子查询中有WHERE pair.id IN &lt;&lt;the user.id list&gt;&gt; 之类的东西吗?还是我做不到?
  • 有类似WHERE pair.id IN &lt;&lt;the user.id list&gt;&gt;的东西;在您的查询中,user.id 列表称为t
  • 不,我的意思是我可以使用外部查询中的&lt;&lt;the user.id list&gt;&gt;(就像我在单个 id 情况下所做的那样,直接使用WHERE id = user.id),而无需将其作为表重新查询@987654338 @?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-06
  • 2021-12-05
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 2018-07-15
相关资源
最近更新 更多