SQL Server:在显示空匹配时连接三个表

时间:2016-10-11 20:17:05

标签: sql sql-server join

我花了几个小时试图找出这个特殊的联接。我有这三个SQL Server表(假设所有必需的索引和外键):

create table [mykey] (keyname varchar(32) not null);
go
create table [myinstance] (
instancename varchar(48) not null);
go
create table [mypermissions] (
keyname varchar(32),
instancename varchar(48),
permission int not null);
go
insert into [mykey] (keyname) values ('test_key_1'), ('test_key_2'), ('test_key_3');
GO
insert into [myinstance] (instancename) values ('sqlexpress'), ('std2008'), ('ent2012');
GO
insert into mypermissions (keyname, instancename, permission) values
    ('test_key_1', 'sqlexpress', 1),
    ('test_key_1', 'std2008', 0),
    ('test_key_2', 'ent2012', 1),
    ('test_key_2', 'sqlexpress', 0)
GO

我正在尝试创建一个联接,该联接显示键名的所有权限,同时还显示缺少特定权限的位置。我希望输出看起来像这样(命令不重要):

keyname     instancename   permission
----------  ------------   ----------
test_key_1  sqlexpress     1
test_key_1  std2008        0
test_key_1  ent2012        NULL
test_key_2  ent2012        1
test_key_2  sqlexpress     0
test_key_2  std2008        NULL
test_key_3  sqlexpress     NULL
test_key_3  std2008        NULL
test_key_3  ent2012        NULL

但它看起来像这样:

keyname     instancename   permission
----------  ------------   ----------
test_key_1  sqlexpress     1
test_key_1  std2008        0
test_key_2  ent2012        1
test_key_2  sqlexpress     0
test_key_3  NULL           NULL

我花了几个小时与各种各样的连接没有运气。也许我想做的事是不可能的。这是我尝试过的最新版本:

select k.keyname, p.instancename, p.permission from mykey k
    full join mypermissions p on (k.keyname = p.keyname)
    full join myinstance i on p.instancename = i.instancename

我正在尝试做什么?

2 个答案:

答案 0 :(得分:6)

在加入第三个表之前,您需要使用CROSS JOIN来获取keyname和instancename的所有组合。看看这个查询

SELECT *
FROM myinstance mi
CROSS JOIN mykey mk

这将输出

instancename    keyname
------------    ----------
sqlexpress      test_key_1
std2008         test_key_1
ent2012         test_key_1
sqlexpress      test_key_2
std2008         test_key_2
ent2012         test_key_2
sqlexpress      test_key_3
std2008         test_key_3
ent2012         test_key_3

您可以使用LEFT JOIN到第三个表格并提取所需的列,如下面的查询所示:

SELECT mk.keyname, mi.instancename, mp.permission
FROM myinstance mi
CROSS JOIN mykey mk
LEFT JOIN mypermissions mp ON mk.keyname = mp.keyname AND mi.instancename = mp.instancename
ORDER BY mk.keyname, mi.instancename

答案 1 :(得分:2)

尝试这样的事情:

select a.keyname, a.instancename, p.permission 
from (select k.keyname, i.instancename from mykey k cross join myinstance i) a
left join mypermissions p on p.keyname = a.keyname and p.instancename = a.instancename