【问题标题】:How can I write a query to match groups of records如何编写查询以匹配记录组
【发布时间】:2018-05-16 23:13:09
【问题描述】:

这是一个令人费解的 SQL 任务。我想用查询来做,而不是用光标单步执行并用“硬方式”来做。

如果我有两个表 TableA 和 TableB,每个表都有一个分组列,如下所示:

TableA             TableB
-------------      -------------
id     group       id     group
------ ------      ------ ------
1      D           1      X
2      D           2      X
3      D           3      Y
4      D           4      Y
4      E           5      Y
5      E           5      Z
5      F           6      Z

注意组名不同同名。

我想知道给定的 TableB 组是否完全由 ID 组成,这些 ID 在 TableA 的任何组中也分组在一起。 TableA 组可以拥有比 TableB 组更多的 ID,只要它具有与 TableB 组相同的所有 ID。 ID 可以在任一表中的多个组中。

从上面的表格中,我应该发现 TableB 中的组 X 匹配 TableA 中的组,但组 Y 和 Z 不匹配。

我尝试了许多不同的查询、子查询、递归 CTE。我只得到了错误的结果和头痛。真实的数据集要大得多,因此性能也应该被考虑在内。不幸的是,这意味着下面的答案中提出的交叉连接解决方​​案将不起作用。

这甚至可以用 SQL 实现吗?

【问题讨论】:

  • 我最终选择了基于光标的解决方案。 (有时,光标是最好的答案!)

标签: sql tsql


【解决方案1】:

此查询的想法是将每个组考虑到每个其他组。然后计算 id 匹配的次数。这涉及到一个cross join 来生成所有组对,然后是一些连接和聚合:

select b.group, a.group
from (select group, count(*) as cnt b group by group) bg cross join
     (select distinct group a) ag left join
     b
     on b.group = bg.group left join
     a
     on a.group = ag.group and a.id = b.id
group by bg.group, ag.group, bg.cnt
having bg.cnt = count(a.id)

【讨论】:

  • 谢谢。从逻辑上讲,这是可行的。不幸的是,我的真实数据集太大,交叉连接不可行。不过,非常聪明的解决方案。如果没有其他人有更高效的方法,我会接受。
【解决方案2】:

这个查询可以给出答案。

SELECT B.[group] 
FROM 
   TableB B
   FULL JOIN TableA A ON B.id = A.id
GROUP BY 
   B.[group]
HAVING 
   COUNT(DISTINCT A.[group]) = 1

【讨论】:

    猜你喜欢
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-26
    • 2020-03-24
    相关资源
    最近更新 更多