【问题标题】:SQL find sets with common members (relational division)SQL 查找具有共同成员的集合(关系除法)
【发布时间】:2013-05-01 07:46:50
【问题描述】:

我有一组单独的“类”和“组”,每组都分配了一个或多个标签。我想为每个组找到包含每个组相同(或更多)标签的类子集。

一些样本数据:

declare @Groups table
(
    GroupID int,
    TagID int
)

insert @Groups
values (1,1),(1,2),(1,3),
    (2,1),(2,2),
    (3,1),(3,2),(3,3),(3,4)

declare @Classes table
(
    ClassID int,
    TagID int
)

insert @Classes
values (1,1),(1,2),
    (2,1),(2,2),
    (3,1),(3,2),(3,3)

select * from @Groups
select * from @Classes

然后输出:

GroupID TagID
1       1
1       2
1       3
2       1
2       2
3       1
3       2
3       3
3       4

ClassID TagID
1       1
1       2
2       1
2       2
3       1
3       2
3       3

示例结果集如下所示:

declare @Results table
(
    GroupID int,
    ClassID int
)

insert @Results
values (1,3),(2,1),(2,2),(2,3),(3,null)

select * from @Results

结果输出:

GroupID ClassID
1       3
2       1
2       2
2       3
3       NULL

我了解这是一个关系除法类型的问题,涉及havingcount。这些帖子描述了我想做什么,但我不知道如何将这些示例应用于上述特定情况:

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql relational-division


    【解决方案1】:

    我认为这也应该有效

    select distinct g.GroupID, c.ClassID
    from @Groups g
        left join @Classes c on g.TagID = c.TagID
    where not exists (
        select *
        from @Groups g2
        where g2.GroupID = g.GroupID
            and g2.TagID not in (
                select TagID
                from @Classes c2
                where c2.ClassID = c.ClassID
            )
        ) or c.ClassID is null
    

    【讨论】:

    • 欢迎来到 SO!和 +1 以获得正确的双重否定方法。我会尽量在生产环境中避免这种情况,因为除非您熟悉它,否则它可能会非常令人费解。
    • 谢谢,标记为为空组正确返回 null 的答案。
    【解决方案2】:

    您可以将表格连接在一起,并要求在类中找到该组中的所有标签:

    select  g.GroupID
    ,       c.ClassID
    from    @Groups g
    join    @Classes c
    on      c.TagID = g.TagID
    group by
            g.GroupID
    ,       c.ClassID
    having  count(c.TagID) =
            (
            select  count(*)
            from    @Groups g2
            where   g2.GroupID = g.GroupID
            )
    

    这不会列出没有匹配类的组,我想不出一个简单的方法。

    Example at SQL Fiddle.

    【讨论】:

    • 谢谢!这看起来可以完成工作,现在远离测试系统,但一旦完全测试就会确认。
    • “要求在类中找到组中的所有标签”......也感谢清晰的逻辑,子查询对我来说是缺失的链接。
    猜你喜欢
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    相关资源
    最近更新 更多