查找与另一个 table 中提供的关系完全相同的所有行

Find all rows with the same exact relations as provided in another table

鉴于这些 table:


Table: 测试

列:


Table:[测试输入]


临时Table:##TestSearchParams

列:


我需要找到在测试输入中有条目的测试,其中输入Table名称完全匹配##TestSearchParams 中的所有条目;生成的测试关系必须与 ##TestSearchParams 中列出的完全相同。

本质上,我只是在寻找给定关系的测试,不多也不少。我正在用 LIKE 和通配符匹配名称,但这是一个旁注,我相信我可以在核心逻辑用于精确匹配之后解决。

这是我当前的查询:

Select *
From   Tests As B
Where  B.testID In (
                       Select ti
                       From   (
                                  Select   (
                                               Select Count(inputsTableName)
                                               From   [Test-Inputs]
                                               Where  [Test-Inputs].testID = B.testID
                                           ) - Count(Distinct i1) As delta,
                                           ti
                                  From     (
                                               Select [Test-Inputs].inputsTableName As i1,
                                                      [Test-Inputs].testID As ti
                                               From   ##TableSearchParams
                                               Join   [Test-Inputs]
                                                   On [Test-Inputs].inputsTableName Like ##TableSearchParams.inputsTableName
                                                      And B.testID = [Test-Inputs].testID
                                           ) As A
                                  Group By ti
                              ) As D
                       Where  D.delta = 0
                   );

当前的问题是他似乎检索到与##TableSearchParams 中的任何条目匹配的测试。在此之前,我尝试了其他几个查询,取得了不同程度的成功。我有工作查询以查找匹配任何参数、所有参数和参数的 none 的测试——我只是无法使该查询正常工作。

以下是一些示例 table 值:

测试

[测试输入]

测试搜索参数


给定的值应该只 return (3, Test3)

这是一个可能的解决方案,它通过为测试中的每条记录获取完整的测试输入集,左连接到搜索参数集,然后通过测试聚合结果并进行两次观察来实现:

首先,如果 Tests 中的记录包含不在搜索参数中的 TestInput,则必须从结果集中排除该记录。我们可以通过查看是否存在上述左连接未在搜索参数 table.

中产生匹配的情况来检查这一点

其次,如果来自 Tests 的记录满足第一个条件,那么我们知道它没有任何多余的 TestInput 记录,因此它可能遇到的唯一问题是是否存在不在其搜索参数中的搜索参数测试输入。如果是这样,那么我们为该测试聚合的记录数将少于搜索参数的总数。

我在这里假设您没有包含重复 TestInput 的测试记录,并且您同样没有使用重复的搜索参数。如果这些假设无效,那么这将变得更加复杂。但如果是,那么这应该有效:

declare @Tests table (testID int, [name] nvarchar(128));
declare @TestInputs table (testID int, inputsTableName nvarchar(128));
declare @TestSearchParams table (inputsTableName nvarchar(128));

-- Sample data.
--
-- testID 1 has only a subset of the search parameters.
-- testID 2 matches the search parameters exactly.
-- testID 3 has a superset of the search parameters.
--
-- Therefore the result set should include testID 2 only.
insert @Tests values
    (1, 'Table A'), 
    (2, 'Table B'), 
    (3, 'Table C');
insert @TestInputs values
    (1, 'X'),
    (2, 'X'),
    (2, 'Y'),
    (3, 'X'),
    (3, 'Y'),
    (3, 'Z');
insert @TestSearchParams values 
    ('X'), 
    ('Y');

declare @ParamCount int;
select @ParamCount = count(1) from @TestSearchParams;

select
    Tests.testID,
    Tests.[name]
from
    @Tests Tests
    inner join @TestInputs Inputs on Tests.testID = Inputs.testID
    left join @TestSearchParams Search on Inputs.inputsTableName = Search.inputsTableName
group by
    Tests.testID,
    Tests.[name]
having
    -- If a group includes any record where Search.inputsTableName is null, it means that
    -- the record in Tests has a TestInput that is not among the search parameters.
    sum(case when Search.inputsTableName is null then 1 else 0 end) = 0 and

    -- If a group includes fewer records than there are search parameters, it means that
    -- there exists some parameter that was not found among the Tests record's TestInputs.
    count(1) = @ParamCount;