SQL加入不在表2中的多个列

时间:2017-05-11 09:39:00

标签: sql-server

设定: 表1 - 列出所有组

表1列 - GroupID,GroupDescription

表2 - 按权限层列出所有站点和关联组。

表2列 - SiteID,SiteName,GroupT1,GroupT2,GroupT3,GroupT4,GroupT5

为了描述这一点,每个站点为5层组,其中每个组对应于该站点的特定级别的权限。

我正在尝试识别未在任何tbl2组层列中使用的tbl1.GroupID,以便删除这些未使用的权限组。

我已尝试将tbl1与tbl2连接起来,但我找不到“on”和“where”的组合来获得我需要的东西。我通常最终得到来自tbl1的条目,这些条目在tbl2中的某些行上为“null”,但它们仍然出现在tbl2上的其他位置。

我需要的是在tbl2中根本没有出现的tbl1行。 在下面的示例数据中,所有“批准者C”组都不用于任何站点,这就是我想要隔离的内容。

由于

表1示例数据:

Group ID    Group Description
T1a         Tier 1 Approver A
T2a         Tier 2 Approver A
T3a         Tier 3 Approver A
T4a         Tier 4 Approver A
T5a         Tier 5 Approver A
T1b         Tier 1 Approver B
T2b         Tier 2 Approver B
T3b         Tier 3 Approver B
T4b         Tier 4 Approver B
T5b         Tier 5 Approver B
T1c         Tier 1 Approver C
T2c         Tier 2 Approver C
T3c         Tier 3 Approver C
T4c         Tier 4 Approver C
T5c         Tier 5 Approver C

表2示例数据

SiteID  SiteDesc    ApprT1  ApprT2  ApprT3  ApprT4  ApprT5
1       Site1       T1A     T2B     T3B     T4B     T5A
2       Site2       T1A     T2A     T3B     T4A     T5A
3       Site3       T1B     T2B     T3B     T4B     T5A
4       Site4       T1B     T2A     T3B     T4A     T5A

尝试查询

select distinct gr.GroupID from
Group_Info$ gi
join Site_Info$ si on
si.ApprT1 is null and
si.ApprT2 is null and
si.ApprT3 is null and
si.ApprT4 is null and
si.ApprT5 is null

2 个答案:

答案 0 :(得分:0)

BEGIN TRAN
--Try This
CREATE TABLE #TABLE1 (GroupId NVARCHAR(5),[Group Description] NVARCHAR(50))
CREATE TABLE #TABLE2 (SiteID INT,SiteDesc NVARCHAR(50), ApprT1 NVARCHAR(50), ApprT2 NVARCHAR(50),ApprT3 NVARCHAR(50),ApprT4  NVARCHAR(50), ApprT5  NVARCHAR(50))

INSERT INTO #TABLE1
SELECT 'T1a','Tier 1 Approver A'  UNION ALL
SELECT'T2a', 'Tier 2 Approver A'UNION ALL
SELECT'T3a','Tier 3 Approver A'UNION ALL
SELECT'T4a','Tier 4 Approver A'UNION ALL
SELECT'T5a','Tier 5 Approver A'UNION ALL
SELECT'T1b','Tier 1 Approver B'UNION ALL
SELECT'T2b','Tier 2 Approver B'UNION ALL
SELECT'T3b','Tier 3 Approver B'UNION ALL
SELECT'T4b','Tier 4 Approver B'UNION ALL
SELECT'T5b','Tier 5 Approver B'UNION ALL
SELECT'T1c','Tier 1 Approver C'UNION ALL
SELECT'T2c','Tier 2 Approver C'UNION ALL
SELECT'T3c','Tier 3 Approver C'UNION ALL
SELECT'T4c','Tier 4 Approver C'UNION ALL
SELECT'T5c','Tier 5 Approver C'


INSERT INTO #TABLE2
SELECT 1,'Site1','T1A','T2B','T3B','T4B','T5A'UNION ALL
SELECT 2,'Site2','T1A','T2A','T3B','T4A','T5A'UNION ALL
SELECT 3,'Site3','T1B','T2B','T3B','T4B','T5A'UNION ALL
SELECT 4,'Site4','T1B','T2A','T3B','T4A','T5A'



SELECT * FROM #TABLE1
SELECT * FROM #TABLE2
SELECT * FROM #TABLE1 WHERE GroupId NOT IN (SELECT ApprT1 FROM #TABLE2 )AND GroupId NOT IN (SELECT ApprT2 FROM #TABLE2 )
AND GroupId NOT IN (SELECT ApprT3 FROM #TABLE2 )AND GroupId NOT IN (SELECT ApprT4 FROM #TABLE2 )AND GroupId NOT IN (SELECT ApprT5 FROM #TABLE2 )

ROLLBACK TRAN

答案 1 :(得分:0)

使用cross apply(values ...)取消忽略ApprT[1-5]Site_Info$中的五个not exists()列,以查找GroupId中不存在Group_Info$的{​​{1}}个那份清单。

select *
from Group_Info$ gi
where not exists (
  select 1
  from Site_Info$ si
    cross apply (values (ApprT1),(ApprT2),(ApprT3),(ApprT4),(ApprT5)
      ) u (GroupId)
  where gi.GroupId = u.GroupId
);

rextester演示:http://rextester.com/OFI50245

返回:

+---------+-------------------+
| GroupId | GroupDescription  |
+---------+-------------------+
| T3a     | Tier 3 Approver A |
| T5b     | Tier 5 Approver B |
| T1c     | Tier 1 Approver C |
| T2c     | Tier 2 Approver C |
| T3c     | Tier 3 Approver C |
| T4c     | Tier 4 Approver C |
| T5c     | Tier 5 Approver C |
+---------+-------------------+

使用common table expression可能会更容易阅读,或者可能不会:

;with cte as (
  select u.GroupId
  from Site_Info$ si
    cross apply (values (ApprT1),(ApprT2),(ApprT3),(ApprT4),(ApprT5)
      ) u (GroupId)
)
select *
from Group_Info$ gi
where not exists (
  select 1
  from cte
  where gi.GroupId = cte.GroupId
  )

隔离“审批者C”的一种方法是GroupDescription中的最后一个字母,我们可以使用聚合以及先前的方法来取消数据,以找到那些未出现在{{1}中的审批者}:

Site_Info$

rextester演示:http://rextester.com/USVYSO98254

返回:

select 
    Approver = right(GroupDescription,1)
  , ApproverGroupCount = count(gi.GroupId)
  , ApproverSiteCount = count(si.GroupId)
from Group_Info$ gi
  left join (
    select distinct u.GroupId
    from Site_Info$ si
      cross apply (values (ApprT1),(ApprT2),(ApprT3),(ApprT4),(ApprT5)
        ) u (GroupId)
      ) si
    on gi.GroupId = si.GroupId
group by right(GroupDescription,1)
having count(si.GroupId) = 0;

我们可以在公共表表达式中包装该查询,并使用它连接到+----------+--------------------+-------------------+ | Approver | ApproverGroupCount | ApproverSiteCount | +----------+--------------------+-------------------+ | C | 5 | 0 | +----------+--------------------+-------------------+ 以返回Approver C的所有行:

Group_Info$

rextester演示:http://rextester.com/USVYSO98254

返回:

with cte as (
  select 
      Approver = right(GroupDescription,1)
  from Group_Info$ gi
    left join (
      select distinct u.GroupId
      from Site_Info$ si
        cross apply (values (ApprT1),(ApprT2),(ApprT3),(ApprT4),(ApprT5)
          ) u (GroupId)
        ) si
      on gi.GroupId = si.GroupId
  group by right(GroupDescription,1)
  having count(si.GroupId) = 0
)
select gi.*
from group_info$ gi
  inner join cte 
    on right(gi.GroupDescription,1) = cte.Approver

参考: