我正在将数据写入表中,并为每批写入的数据分配一个“group-id”。为了说明这一点,请考虑下表。
GroupId Value
------- -----
1 a
1 b
1 c
2 a
2 b
3 a
3 b
3 c
3 d
在此示例中,存在三组数据,每组数据具有相似但不同的值。
如何查询此表以查找包含给定值集的组?例如,如果我查询 (a,b,c),结果应为组 1。类似地,查询 (b,a) 应结果为组 2,查询 (a,b,c,e) 应结果为组 1。应该导致空集。
我可以编写一个执行以下步骤的存储过程:
- 从群组中选择不同的 GroupId - 并存储在本地
- 对于每个不同的 GroupId:在输入值和表值(对于组)之间执行设置差异(
异常(exception)
),反之亦然 - 如果两个集合差值运算都生成空集,则返回 GroupId
这似乎有点过分,我希望利用 SQL 中的其他一些命令来简化。是否有更简单的方法可以在此上下文中执行集合比较,或者选择包含查询的确切输入值的组 ID?
最佳答案
这是一个集合内的查询。我喜欢使用group by
和having
来解决它:
select groupid
from GroupValues gv
group by groupid
having sum(case when value = 'a' then 1 else 0 end) > 0 and
sum(case when value = 'b' then 1 else 0 end) > 0 and
sum(case when value = 'c' then 1 else 0 end) > 0 and
sum(case when value not in ('a', 'b', 'c') then 1 else - end) = 0;
having
子句中的前三个条件检查每个元素是否存在。最后一个条件检查是否没有其他值。这种方法非常灵活,适用于您要查找的值的各种排除和包含条件。
编辑:
如果你想传入一个列表,可以使用:
with thelist as (
select 'a' as value union all
select 'b' union all
select 'c'
)
select groupid
from GroupValues gv left outer join
thelist
on gv.value = thelist.value
group by groupid
having count(distinct gv.value) = (select count(*) from thelist) and
count(distinct (case when gv.value = thelist.value then gv.value end)) = count(distinct gv.value);
此处的 having
子句计算匹配值的数量,并确保其与列表的大小相同。
编辑: 由于缺少表别名,查询编译失败。使用正确的表别名更新。
关于sql - 考虑到应出现在组行中的数据,如何确定表中是否存在一组数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22104670/