0

我的问题是只显示分组唯一数据集的 id。一个简单的例子最好:

| id | color |
--------------
| 1  | red   |
--------------
| 1  | green |
--------------
| 1  | blue  |
--------------
| 2  | red   |
--------------
| 2  | green |
--------------
| 2  | blue  |
--------------
| 3  | red   |
--------------
| 3  | blue  |
--------------
| 3  | yellow|
--------------
| 3  | purple|
--------------

ID 1 和 id 2 具有相同的数据子集(红色、绿色、蓝色),因此结果表应该只包含 1 或 2:

| id |
------
| 1  |
------
| 3  | 
------

我猜这个相对基本的问题被问了多次,但我无法确定会产生结果的特定关键字。

4

2 回答 2

1

SQL 是面向集合的,所以让我们试试这个:

唯一 ID 是不存在具有相同颜色集的其他 ID 的 ID。

为了确定两个 ID 是否具有相同的颜色集,我们将它们彼此相减EXCEPT(这就是这样做的)并测试结果在两个方向上是否为空:

SELECT id
FROM (SELECT DISTINCT id FROM t) AS t1
WHERE NOT EXISTS (SELECT id FROM (SELECT DISTINCT id FROM t) AS t2
                  WHERE t2.id < t1.id
                    AND NOT EXISTS (SELECT color FROM t WHERE id = t1.id
                                    EXCEPT
                                    SELECT color FROM t WHERE id = t2.id)
                    AND NOT EXISTS (SELECT color FROM t WHERE id = t2.id
                                    EXCEPT
                                    SELECT color FROM t WHERE id = t1.id));

SQL小提琴

于 2013-06-06T13:56:04.623 回答
1

虽然 SQLite 有group_concat(),但它在这里无济于事,因为连接元素的顺序是任意的。这是最简单的方法。

相反,我们必须以相关的方式考虑这一点。想法是执行以下操作:

  1. 计算两个 id 共有的颜色数量
  2. 计算每个id上的颜色数
  3. 选择这三个值相等的 id 对
  4. 通过对中的最小 id 识别每一对

然后最小值的不同值是您想要的列表。

以下查询采用这种方法:

select distinct MIN(id2)
from (select t1.id as id1, t2.id as id2, count(*) as cnt
      from t t1 join
           t t2
           on t1.color = t2.color
      group by t1.id, t2.id
     ) t1t2 join
     (select t.id, COUNT(*) as cnt
      from t
      group by t.id
     ) t1sum
     on t1t2.id1 = t1sum.id and t1sum.cnt = t1t2.cnt join
     (select t.id, COUNT(*) as cnt
      from t
      group by t.id
     ) t2sum
     on t1t2.id2 = t2sum.id and t2sum.cnt = t1t2.cnt
group by t1t2.id1, t1t2.cnt, t1sum.cnt, t2sum.cnt

我实际上是在 SQL Server 中通过将此with子句放在前面来测试的:

with t as (
      select 1 as id, 'r' as color union all
      select 1, 'g' union all
      select 1, 'b' union all
      select 2 as id, 'r' as color union all
      select 2, 'g' union all
      select 2, 'b' union all
      select 3, 'r' union all
      select 4, 'y' union all
      select 4, 'p' union all
      select 5 as id, 'r' as color union all
      select 5, 'g' union all
      select 5, 'b' union all
      select 5, 'p'
     )
于 2013-06-06T13:26:12.927 回答