【问题标题】:SQL Server: Joining three tables while showing null matchesSQL Server:在显示空匹配项时加入三个表
【发布时间】:2016-10-11 20:17:04
【问题描述】:

我花了几个小时试图找出这个特定的连接。我有这三个 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

我正在尝试做的事情可能吗?

【问题讨论】:

    标签: sql sql-server join


    【解决方案1】:

    在加入第三张表之前,您需要使用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
    

    【讨论】:

      【解决方案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
      

      【讨论】:

      • 这里基于什么内部join?
      • 这是一个交叉连接,第一个表中的所有行乘以第二个表中的所有行。运行它来看看它会产生什么。
      • 当我运行这个查询时,我得到这个错误Incorrect syntax near ')'. 你错过了CROSS 关键字吗? :)
      • 你还需要修正isntancename中的错字;)
      猜你喜欢
      • 1970-01-01
      • 2019-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多