重复匹配多行的一组详细信息类型

时间:2017-03-16 15:43:02

标签: sql-server join

我有一套有关名册信息的详细信息。

我有一张名册详细信息表。每个人都有一个ID#,以及该ID#的大约50行详细信息。 PK是ID#,详细信息类型和日期。

我正在尝试将子查询的结果连接到名单详细信息表中的每一行,以查找人们缺少哪些详细信息类型。

我可以通过个人实现我想要的结果:

select *
from (

    -- a big sub-query yielding 39 lines of the detail types I want

) list_of_details
left join textDetail td
    on td.detailType = list_of_details.detailType
    and td.sid_member = 2071
order by dt.sid_detailType

收益率:

detailType     ID          detailType     date_start              value_detail
-------------- ----------- -------------- ---------------------------------
1              2071        1              2017-03-14 00:00:00.000 test
1              2071        1              2017-03-14 16:58:50.037 NULL
2              2071        2              2017-03-14 00:00:00.000 test
2              2071        2              2017-03-14 16:58:50.037 NULL
3              NULL        NULL           NULL                    NULL
4              2071        4              2017-03-14 16:58:50.037 NULL
16             NULL        NULL           NULL                    NULL
17             2071        17             2017-03-14 16:58:50.037 NULL
18             2071        18             2017-03-14 16:58:50.037 NULL
19             2071        19             2017-03-14 16:58:50.037 NULL
20             2071        20             2017-03-14 16:58:50.037 NULL
21             2071        21             2017-03-14 16:58:50.037 NULL
22             2071        22             2017-03-14 16:58:50.037 NULL
23             2071        23             2017-03-14 16:58:50.037 NULL
24             2071        24             2017-03-14 16:58:50.037 NULL
25             2071        25             2017-03-14 16:58:50.037 NULL
27             2071        27             2017-03-14 16:58:50.037 NULL
28             2071        28             2017-03-14 16:58:50.037 NULL
33             NULL        NULL           NULL                    NULL
34             NULL        NULL           NULL                    NULL
35             2071        35             2017-03-14 16:58:50.037 NULL
36             2071        36             2017-03-14 16:58:50.037 NULL
37             2071        37             2017-03-14 16:58:50.037 NULL
38             2071        38             2017-03-14 16:58:50.037 NULL
39             2071        39             2017-03-14 16:58:50.037 NULL
40             2071        40             2017-03-14 16:58:50.037 NULL
41             2071        41             2017-03-14 16:58:50.037 NULL
42             2071        42             2017-03-14 16:58:50.037 NULL
46             2071        46             2017-03-14 16:58:50.037 NULL
47             2071        47             2017-03-14 16:58:50.037 NULL
48             2071        48             2017-03-14 16:58:50.037 NULL
51             2071        51             2017-03-14 16:58:50.037 NULL
52             2071        52             2017-03-14 16:58:50.037 NULL
53             2071        53             2017-03-14 16:58:50.037 NULL
54             2071        54             2017-03-14 16:58:50.037 NULL
55             2071        55             2017-03-14 16:58:50.037 NULL
56             2071        56             2017-03-14 16:58:50.037 NULL
57             2071        57             2017-03-14 16:58:50.037 NULL
58             NULL        NULL           NULL                    NULL

我并不担心NULL列中的value_detail,这是测试用户。

我需要针对几百个用户重复此查询,并找到他们缺少的条目。例如,上述人员缺少detailType 3,16,33,34,58

- 编辑 -

删除and td.sid_member = 2071只会产生匹配的行。在这种情况下,sid_member 2071的结果会排除detailType未出现的行,这就是我想要的。

添加where td.sid_member is null不会返回结果

2 个答案:

答案 0 :(得分:0)

在现有查询中删除或替换此行:

 and td.sid_member = 2071

答案 1 :(得分:0)

你几乎就在那里......你只需要在textDetail方面检查NULL:

left join textDetail td
    on td.detailType = list_of_details.detailType
WHERE td.sid_member IS NULL
order by dt.sid_detailType

这基本上可以为您提供所有不匹配的内容。

*编辑*

好的......既然你没有给我们你的桌子结构,我想到了更多......

如果您需要ID以及缺少的详细信息类型,则需要使用交叉连接创建包含所有可能详细信息类型的ID的主列表。然后,您可以离开加入该主列表,并按照唯一ID获取缺少的详细信息类型。

SELECT xid.ID, xid.detailType
FROM
   (SELECT i.ID, d.detailType
   FROM
   (SELECT DISTINCT ID FROM textDetail) as i
   cross join (SELECT DISTINCT detailType FROM list_of_details) as d
   ) as xid
left outer join textDetail td
    on xid.ID = td.ID
    AND xid.detailType = td.detailType
WHERE td.detailType IS NULL
ORDER BY xid.ID, xid.detailType

现在,这将为您提供每个ID的不匹配