我花了几个小时试图找出这个特殊的联接。我有这三个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
我正在尝试做什么?
答案 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