2016-08-21 37 views
2

我有以下问题,我知道如何从同一个表中找到缺少的记录,但我无法知道记录从哪里丢失:SQL Server 2012比较记录并根据动态位置找到丢失的记录

这里是主表

Location  | Role | Subrole 
A            | R1    | SR1 
A            | R1    | SR2 
A            | R1    | SR3 
B            | R1    | SR1 
B            | R1    | SR2 
B            | R1    | SR3 
C            | R1    | SR1 
C            | R1    | SR2 
D            | R1    | SR1 

位置的是主地点和所有其他位置应该是比较A.我的最终目标是拥有这样的:

MasterLocation | MasterRole | MasterSubrole | Location | Role | Subrole 
     A        | R1        | SR1          |    B     | R1   | SR1 
     A        | R1        | SR2          |    B     | R1   | SR2 
     A        | R1        | SR3          |    B     | R1   | SR3 
     A        | R1        | SR1          |    C     | R1   | SR1 
     A        | R1        | SR2          |    C     | R1   | SR2 
     A        | R1        | SR3          |    C     | R1  | MISSING OR NULL 
     A        | R1        | SR1          |    D     | R1   | SR1 
     A        | R1        | SR2          |    D     | R1   | MISSING OR NULL 
     A        | R1        | SR3          |    D     | R1   | MISSING OR NULL 

我已创建2个临时表

CREATE TABLE #LocA 
( 
    Location Varchar(1), 
    Role Varchar(2), 
    SubRole VARCHAR(20) 
) 

CREATE TABLE #AllOthers 
( 
    Location VARCHAR(1), 
    Role VARCHAR(2), 
    SubRole VARCHAR(20) 
) 

INSERT INTO #LocA 
    SELECT 
     Location, Role, SubRole 
    FROM 
     TABLE 
    WHERE 
     Location = 'A' 

INSERT INTO #AllOthers 
    SELECT 
     Location, Role, SubRole 
    FROM 
     TABLE 
    WHERE 
     Location != 'A' 

SELECT 
    A.Location AS MasterLocation, 
    A.Role AS MasterRole, 
    A.SubRole AS MasterSubrole 
    L.Location, 
    L.Role, 
    L.Subrole 
FROM 
    #LocA AS A 
LEFT JOIN 
    #Allothers AS L ON A.Role = L.Role 
        AND A.SubRole = L.Subrole 

我越来越

MasterLocation  | MasterRole  | MasterSubrole | Location | Role|Subrole 

A                       | R1              | SR1                 |     B        | R1      | SR1 
A                       | R1              | SR2                 |     B        | R1      | SR2 
A                       | R1              | SR3                 |     B        | R1      | SR3 
A                       | R1              | SR1                 |     C        | R1      | SR1 
A                       | R1              | SR2                 |     C        | R1      | SR2 
A                       | R1              | SR3                 |     NULL   | NULL   | NULL 
A                       | R1              | SR1                 |     D        | R1      | SR1 
A                       | R1              | SR2                 |     NULL   | NULL   | NULL 
A                       | R1              | SR3                 |     NULL   | NULL   | NULL 

所以我其实不知道在哪里子角色是从,C或D缺失(此表有数百个地点。)

+0

是在'在MasterSubrole'正确的价值目标表? – shawnt00

+0

对不起,你是对的,我纠正了Master sub的作用。这是由于复制粘贴 – Overdrive

回答

1

交叉连接的常见用法是在这种类型的问题中,您需要显示所有可能的组合。查询的前半部分创建了该组值,然后左连接通过跨多维的复合连接来附加数据值。

select 
    m.Location as MasterLocation, 
    m.Role as MasterRole, 
    m.Subrole as MasterSubrole, 
    l.Location, 
    coalesce(t.Role, 'Missing role') as Role, 
    coalesce(t.Subrole, 'Missing subrole') as Subrole 
from 
    T as m 
    cross join 
    (select distinct Location from T where Location <> 'A') as l 
    left outer join T as t 
     on  l.Location = t.Location 
      and m.Role = t.Role 
      and m.Subrole = t.SubRole 
where 
    m.Location = 'A'; 

您可能希望避免提字面值不止一次A更在查询所以这里是一个另类。

select 
    m.Location as MasterLocation, 
    m.Role as MasterRole, 
    m.Subrole as MasterSubrole, 
    l.Location, 
    coalesce(t.Role, 'Missing role') as Role, 
    coalesce(t.Subrole, 'Missing subrole') as Subrole 
from 
    (select * from T where Location = 'A') as m 
    cross apply 
    (select distinct Location from T where Location <> m.Location) as l 
    left outer join T as t 
     on  l.Location = t.Location 
      and m.Role = t.Role 
      and m.Subrole = t.SubRole; 

如果你在数据空,你想匹配起来你可能想加入这样:

 on  l.Location = t.Location 
      and coalesce(m.Role, '[email protected]') = coalesce(t.Role, '[email protected]') 
      and coalesce(m.Subrole, '[email protected]#') = coalesce(t.SubRole, '[email protected]#'); 

http://rextester.com/MNSU54881

+0

我今天能够在更大范围内测试这个,这非常好,非常感谢。我曾考虑过添加地点的交叉申请,但我在执行中迷路了。谢谢! – Overdrive