【问题标题】:How to select all records from one table that exactly match another table in SQL Server?如何从一个表中选择与 SQL Server 中的另一个表完全匹配的所有记录?
【发布时间】:2026-01-04 20:50:02
【问题描述】:

我有一个关于 select 的棘手问题:我有这个表结构:

declare @one as table (serviceid int null)

declare @two as table (id int null, serviceid int null)

insert into @two 
values (15,195),(15,84),(16,195),(16,84),(16,NULL),(17,195),(17,84),(17,8)

我需要得到完全匹配的 @two.ID(与 serviceid 和 count intable @two 匹配)

场景 1:

insert into @one values (195),(84)

我只需要获取 ID-15,因为所有 serviceid 都匹配并且表 @one 中的记录数为 2。

场景 2:

Insert into @one values (195),(84),(8)

我只需要获取 ID- 16 和 17,17:因为所有 serviceid 都匹配并且表 @one 中的记录数为 3。,16:因为两个服务匹配,表 @one 中的记录数为 3,NULL 表示“无关紧要”(谁)

你有什么想法吗?

【问题讨论】:

    标签: sql sql-server select matching


    【解决方案1】:

    恐怕您接受的答案是错误的(正如您在评论中注意到的那样)。这是工作查询:

    -- tables declaration ---------------------------------------------------------------------
    declare @one as table (serviceid int null)
    declare @two as table (id int null, serviceid int null)
    -- values insert --------------------------------------------------------------------------
    insert into @two values (15,195),(15,84),(16,195),(16,84),(16,NULL),(17,195),(17,84),(17,8)
    insert into @one values (195),(84)
    -- actual query ---------------------------------------------------------------------------
    select id from (
    select id,
           --check, where we have null records in @one caused by null values in @two, which is acceptable (assifgned value when acceptable = 0)
           case when ([ONE].serviceid is not null and [TWO].serviceid is not null) or ([ONE].serviceid is null and [TWO].serviceid is null) then 0 else 1 end [IsMatched]
    from (
        select *, COUNT(*) over (partition by id) as [idCount] from @two
    ) [TWO] left join (
        select serviceid, COUNT(*) over (partition by (select null)) [idCount] from @one
    ) [ONE] on ([TWO].idCount = [ONE].idCount and [TWO].serviceid = [ONE].serviceid)
    ) [a] group by id
    having SUM(IsMatched) = 0
    

    【讨论】:

    • 谢谢。这正是我想要的;)
    【解决方案2】:
    declare @one as table (serviceid int null)
    
    declare @two as table (id int null, serviceid int null)
    
    insert into @two values (15,195),(15,84),(16,195),(16,84),(16,NULL),(17,195),(17,84),(17,8);
    --insert into @one values (195),(84);
    Insert into @one values (195),(84),(8)
    
    select distinct t.id
    from @two t
    where exists (select * from @one o where t.serviceid = o.serviceid)
          and (select count(*) from @one) = (select count(*) from @two t1 where t1.id = t.id);
    

    【讨论】:

    • 好主意。但万一INSERT INTO @one VALUES (195) ,(84) ,(7) 我得到16和17,但只需要得到16
    • 表示我没听懂你的意思。如果 (17,195) 给你一个匹配 @one 并且 17 在两个中的计数是 3 等于一个中的行数,你为什么不考虑 17 作为答案?
    • @user3616309 好的,我首先认为只有计数应该匹配,而服务也应该匹配,我更新了我的答案,现在我只计算匹配的那些。
    最近更新 更多