sql - 子查询与多表连接
问题描述
我有 3 个表 A、B、C。我想列出交叉点数。
方式1:-
select count(id) from A a join B b on a.id = b.id join C c on B.id = C.id;
结果计数 - X
方式2:-
SELECT count(id) FROM A WHERE id IN (SELECT id FROM B WHERE id IN (SELECT id FROM C));
结果计数 - Y
每个查询中的结果计数不同。究竟是什么问题?
解决方案
AJOIN
可以乘以行数以及过滤掉行。
在这种情况下,第二个计数应该是正确的,因为没有重复计算 - 假设id
在a
. 如果没有,则需要count(distinct a.id)
.
等效的 usingJOIN
将使用COUNT(DISTINCT)
:
select count(distinct a.id)
from A a join
B b
on a.id = b.id join
C c
on B.id = C.id;
我提到这一点是为了完整性,但不推荐这种方法。将行数相乘只是为了删除它们distinct
是低效的。
在许多数据库中,最有效的方法可能是:
select count(*)
from a
where exists (select 1 from b where b.id = a.id) and
exists (select 1 from c where c.id = a.id);
id
注意:这假设列上有索引,并且id
在a
.
推荐阅读
- android - 如何在片段中调用 AlertDialog?
- database - 规范化 数据库查找键、范式、分解
- node.js - 通过 GKE 将 Pub/Sub 用于 Google Cloud Storage
- python - 在画布上一式三份的相同内容
- java - Optaplanner 约束流除“内部连接”之外的其他连接类型
- reactjs - 使用功能标志控制 next.js 中路由器的条件渲染
- r - 根据 R 中另一个数据框的平均值创建新数据框
- xargs - 为什么命令不能从 bash 工作的 xargs 工作?
- python - 如何在while循环中在同一个子图中创建多个子图?:Python
- python - Python 套接字 io 使用会话 id (sid) 读取数据