如何写这个连接?

时间:2018-06-15 09:44:20

标签: tsql left-join

我正在努力在两个表之间编写连接。更容易向您展示而不是描述它,但Stackoverflow坚持更多的单词,所以我们在这里......我有两个表可以在两列上左键联接。所有行都存在于Tbl1中,而不是缺少行。 Tbl2中的数据存在一些差距。但是,如果在连接中缺少Tbl2中不在Tbl1(DBName)中的列,则需要将其返回为NULL。就像我说的,更容易告诉你!见下文。

IF OBJECT_ID('tempdb..#tbl1') IS NOT NULL DROP TABLE #tbl1
IF OBJECT_ID('tempdb..#tbl2') IS NOT NULL DROP TABLE #tbl2
go

CREATE TABLE #tbl1
(
Name varchar(8),
StartDate datetime
)
go

INSERT INTO #tbl1 VALUES ( 'Server1','2018-01-01 00:00:00')
INSERT INTO #tbl1 VALUES ( 'Server1','2018-02-01 00:00:00')
INSERT INTO #tbl1 VALUES ( 'Server1','2018-03-04 00:00:00')

INSERT INTO #tbl1 VALUES ( 'Server2','2018-01-05 00:00:00')
INSERT INTO #tbl1 VALUES ( 'Server2','2018-02-04 00:00:00')
INSERT INTO #tbl1 VALUES ( 'Server2','2018-03-10 00:00:00')
INSERT INTO #tbl1 VALUES ( 'Server2','2018-05-12 00:00:00')

INSERT INTO #tbl1 VALUES ( 'Server3','2018-01-12 00:00:00')

INSERT INTO #tbl1 VALUES ( 'Server4','2018-02-23 00:00:00')
GO

CREATE TABLE #tbl2
(
Name varchar(8),
StartDate datetime,
DBName varchar(8)
)
go

INSERT INTO #tbl2 VALUES ( 'Server1','2018-01-01 00:00:00', 'MyDB1')
INSERT INTO #tbl2 VALUES ( 'Server1','2018-02-01 00:00:00', 'MyDB1')
INSERT INTO #tbl2 VALUES ( 'Server1','2018-03-04 00:00:00', 'MyDB1')

INSERT INTO #tbl2 VALUES ( 'Server1','2018-01-01 00:00:00', 'MyDB2')
INSERT INTO #tbl2 VALUES ( 'Server1','2018-02-01 00:00:00', 'MyDB2')
INSERT INTO #tbl2 VALUES ( 'Server1','2018-03-04 00:00:00', 'MyDB2')

INSERT INTO #tbl2 VALUES ( 'Server1','2018-01-01 00:00:00', 'MyDB3')
--INSERT INTO #tbl1 VALUES ( 'Server1','2018-02-01 00:00:00', 'MyDB2')  -- let's say this is missing
INSERT INTO #tbl2 VALUES ( 'Server1','2018-03-04 00:00:00', 'MyDB3')

INSERT INTO #tbl2 VALUES ( 'Server2','2018-01-05 00:00:00', 'MyDB4')
INSERT INTO #tbl2 VALUES ( 'Server2','2018-02-04 00:00:00', 'MyDB4')
INSERT INTO #tbl2 VALUES ( 'Server2','2018-03-10 00:00:00', 'MyDB4')
INSERT INTO #tbl2 VALUES ( 'Server2','2018-05-12 00:00:00', 'MyDB4')

INSERT INTO #tbl2 VALUES ( 'Server2','2018-01-05 00:00:00', 'MyDB5')
INSERT INTO #tbl2 VALUES ( 'Server2','2018-02-04 00:00:00', 'MyDB5')
--INSERT INTO #tbl1 VALUES ( 'Server2','2018-03-10 00:00:00', 'MyDB5')  -- let's say this is missing
INSERT INTO #tbl2 VALUES ( 'Server2','2018-05-12 00:00:00', 'MyDB5')

INSERT INTO #tbl2 VALUES ( 'Server3','2018-01-12 00:00:00', 'MyDB6') 
GO


SELECT 
    a.*,
    b.DBName
FROM 
     #tbl1 a
     LEFT JOIN #tbl2 b
     ON a.Name = b.Name AND a.StartDate = b.StartDate
ORDER BY
    a.Name,
    b.DBName,
    a.StartDate desc   

上述查询可以完成您对此输出所期望的...

Name    StartDate           DBName
Server1 2018-03-04 00:00:00.000 MyDB1
Server1 2018-02-01 00:00:00.000 MyDB1
Server1 2018-01-01 00:00:00.000 MyDB1
Server1 2018-03-04 00:00:00.000 MyDB2
Server1 2018-02-01 00:00:00.000 MyDB2
Server1 2018-01-01 00:00:00.000 MyDB2
Server1 2018-03-04 00:00:00.000 MyDB3
Server1 2018-01-01 00:00:00.000 MyDB3
Server2 2018-05-12 00:00:00.000 MyDB4
Server2 2018-03-10 00:00:00.000 MyDB4
Server2 2018-02-04 00:00:00.000 MyDB4
Server2 2018-01-05 00:00:00.000 MyDB4
Server2 2018-05-12 00:00:00.000 MyDB5
Server2 2018-02-04 00:00:00.000 MyDB5
Server2 2018-01-05 00:00:00.000 MyDB5
Server3 2018-01-12 00:00:00.000 MyDB6
Server4 2018-02-23 00:00:00.000 NULL

我想要的是输出,其中包含DBName的NULL值,其中#Tbl2中缺少该行...

Server1 2018-03-04 00:00:00.000 MyDB1
Server1 2018-02-01 00:00:00.000 MyDB1
Server1 2018-01-01 00:00:00.000 MyDB1
Server1 2018-03-04 00:00:00.000 MyDB2
Server1 2018-02-01 00:00:00.000 MyDB2
Server1 2018-01-01 00:00:00.000 MyDB2
Server1 2018-03-04 00:00:00.000 MyDB3
Server1 2018-02-01 00:00:00.000 NULL     -- <<<<<<<<<<<<
Server1 2018-01-01 00:00:00.000 MyDB3
Server2 2018-05-12 00:00:00.000 MyDB4
Server2 2018-03-10 00:00:00.000 MyDB4
Server2 2018-02-04 00:00:00.000 MyDB4
Server2 2018-01-05 00:00:00.000 MyDB4
Server2 2018-05-12 00:00:00.000 MyDB5
Server2 2018-02-04 00:00:00.000 MyDB5
Server2 2018-03-10 00:00:00.000 NULL     -- <<<<<<<<<<<<<<<<
Server2 2018-01-05 00:00:00.000 MyDB5
Server3 2018-01-12 00:00:00.000 MyDB6
Server4 2018-02-23 00:00:00.000 NULL

提前致谢!

1 个答案:

答案 0 :(得分:0)

我可以想到的唯一一个问题是,即使左表中没有匹配的行,您也希望返回右表中的值?

如果是这种情况,您可以使用2018-06-15 09:43:39.025761+00 full outer join的组合来返回将两个表合并为一个合并输出的完整数据集。所以不是这个isnull

select

运行:

select a.Name
      ,a.StartDate
      ,b.DBName
from #tbl1 a
    left join #tbl2 b
        on a.Name = b.Name
            and a.StartDate = b.StartDate
order by a.Name
        ,b.DBName
        ,a.StartDate desc

为了得到这个,这与你想要的输出并不完全一致但是我相当确定没有进一步的信息你的是不可能的:

select isnull(a.Name,b.Name) as Name
      ,isnull(a.StartDate,b.StartDate) as StartDate
      ,case when a.Name is not null then b.DBName end as DBName
from @tbl1 a
    full outer join @tbl2 b
        on a.Name = b.Name
            and a.StartDate = b.StartDate
order by Name
        ,DBName
        ,StartDate desc