sql - 与动态数量的表相交
问题描述
我有两个关系,a
并且b
,具有由给出的属性
CREATE TABLE a (id int, b_id int)
CREATE TABLE b (id int)
为此,我可以假设 in 中的所有值对a
和 in 中的所有值b
都是唯一的,并且将基于 SQL Server 2016 数据库。
的给定元素b
定义了a.id
由那些元素对应a.b_id
的给定值的子集,我的目标是产生所有这些子集的交集。
比如说,它a
包含六个值,
INSERT INTO a VALUES (1, 1), (1, 2), (1, 3), (2, 2), (3, 2), (3, 3)
那么预期的结果将包括以下内容:
b: (1), (2), (3). Expected result: (1)
b: (1), (2). Expected result: (1)
b: (2). Expected result: (1), (2), (3)
b: (2), (3). Expected result: (1), (3)
b: [Empty]. Expected result: (1), (2), (3)
使用唯一性,对于非空的情况b
,这可以通过
SELECT a.id FROM a
JOIN b on a.b_id = b.id
GROUP BY a.id
HAVING COUNT(a.id) = (SELECT COUNT(*) FROM b)
但这感觉很笨拙,因为 SQL 有一个INTERSECT
现成的运算符,如果我在 LINQ 中编写相同的查询,我会简单地聚合交叉点。b
如果不将其视为特殊情况,它也无法在空的情况下产生所需的结果。
所以,问题变成了:是否有一种更惯用的方式来执行上述查询,这也适用于 trivial b
?
解决方案
您可以使用以下方法扩展处理空集案例的方法:
SELECT a.id
FROM a
LEFT JOIN b on a.b_id = b.id
GROUP BY a.id
HAVING COUNT(b.id) = (SELECT COUNT(*) FROM b);
DBFiddle 演示 | DBFiddle Demo - 所有测试用例
额外:瞬态数据(在第二个演示中使用)
编辑:
另一种处理空集和离开的方法INNER JOIN
:
SELECT a.id FROM a
JOIN b on a.b_id = b.id
GROUP BY a.id
HAVING COUNT(a.id) = (SELECT COUNT(*) FROM b)
UNION
SELECT a.id
FROM a
WHERE NOT EXISTS (SELECT 1 FROM b);
推荐阅读
- svg - THREE.ExtrudeBufferGeometry 的多边形很少
- r - 将显着性星添加到优势比图 (ggplot)
- python - python sqlalchemy原始查询非常慢
- python - 无法将字符串转换为浮点数:'100.0000%'
- c++ - 使用 std::thread 时与 g++/OpenMP 相关的错误?
- javascript - 将值添加到队列并在显示它们之前等待
- reactjs - 如何在地图上显示3s平面中的一条线?
- rxjs - 如何在 Observable NestJS 中引发异常?
- html - 页面刷新后将数据保存在div中
- php - 如何使用 php 读取文件名?