我有两个要联接的表,如下所示:
表1
Code1 | Code2 | Date(1) | Amount(1)
A | AA | 201802 | 100
A | AA | 201803 | 50
A | AA | 201804 | 30
表2
Code1 | Code2 | Date(2) | Amount(2)
A | AA | 201801 | 20
A | AA | 201802 | 10
A | AA | 201803 | 10
我希望结果表看起来像这样:
结果
Code1 | Code2 | Date(1) | Date(2) | Amount(1) | Amount(2)
A | AA | NULL | 201801 | NULL | 20
A | AA | 201802 | 201802 | 100 | 10
A | AA | 201803 | 201803 | 50 | 10
A | AA | 201804 | NULL | 30 | NULL
所以我需要加入这两个表
on table1.Code1 = table2.Code1 AND table1.Code2 = table2.Code2 AND table1.Date(1) = table2.Date(2)
但是我还希望日期与null不匹配的行是与不匹配表相关的列(例如,在我的示例中为Date(1) = 201804
的行)。
我尝试用左,右和外联接来连接这两个表,但是我仍然无法成功获得带有空值的行(可能是因为该特定缺失行不存在Code1和Code2)
也许交叉申请可能有效,但是我不确定如何执行。
我想要一种最有效的性能方法,因为这是包含大量数据和大量计算的大型查询的一部分。
更新: 我使用的代码是:
Select table1.Code 1, table1.Code2, Table1.Date(1), table2.Date(2), table1.Amount(1), table2.amount(2)
FROM Table1
Full Outer Join
table2 ON
table1.Code1 = table2.Code1
AND table1.Code2 = table2.Code2
AND table1.date(1) = table2.date(2)
哪个给我以下结果:
Code1 | Code2 | Date(1) | Date(2) | Amount(1) | Amount(2)
A | AA | 201802 | 201802 | 100 | 10
A | AA | 201803 | 201803 | 50 | 10
缺少这两行:
A | AA | NULL | 201801 | NULL | 20
A | AA | 201804 | NULL | 30 | NULL
答案 0 :(得分:1)
您可以尝试这个。
--sample dataset
DECLARE @tab1 as table (
Code1 varchar(10),
Code2 varchar(10),
Date1 int,
Amount1 int )
insert into @tab1
values
('A', 'AA', 201802, 100),
('A', 'AA', 201803, 50),
('A', 'AA', 201804, 30),
('B', 'AA', 201802, 100) --additional
DECLARE @tab2 as table (
Code1 varchar(10),
Code2 varchar(10),
Date2 int,
Amount2 int )
insert into @tab2
values
('A', 'AA', 201802, 100),
('A', 'AA', 201803, 50),
('A', 'AA', 201801, 30)
查询
SELECT *
FROM (
select
coalesce(table1.Code1,table2.Code1) as Code1,
coalesce(table1.Code2,table2.Code2) as Code2,
table1.Date1,
table2.Date2,
table1.Amount1,
table2.amount2
FROM @tab1 as Table1
Full Outer Join @tab2 as table2 ON
table1.Code1 = table2.Code1
AND table1.Code2 = table2.Code2
AND table1.date1= table2.date2
) as t1
CROSS APPLY ( --to exclude records not matched by "Code 1 and Code 2"
SELECT top 1
Code1
FROM @tab2 as t
where t.Code1 = t1.Code1
and t.Code2 = t1.Code2
) as c
ORDER BY t1.Date1
或类似这样:
select
coalesce(table1.Code1,table2.Code1) as Code1,
coalesce(table1.Code2,table2.Code2) as Code2,
table1.Date1,
table2.Date2,
table1.Amount1,
table2.amount2
FROM @tab1 as Table1
Full Outer Join @tab2 as table2 ON
table1.Code1 = table2.Code1
AND table1.Code2 = table2.Code2
AND table1.date1= table2.date2
where exists (select null --to exclude records not matched by "Code 1 and Code 2"
from @tab2 as t2
where coalesce(table1.Code1,table2.Code1) = t2.Code1
and coalesce(table1.Code2,table2.Code2) = t2.Code2)
ORDER BY table1.Date1
答案 1 :(得分:0)
如果您将CodeX列设为ISNULL,则更新的查询应该可以使用。
declare @t1 table (Code1 varchar(4), Code2 varchar(4), Date1 date, Amount1 int)
declare @t2 table (Code1 varchar(4), Code2 varchar(4), Date2 date, Amount2 int)
insert into @t1
values
('A', 'AA', '2018-02-01', 100 ),
('A', 'AA', '2018-03-01', 50 ),
('A', 'AA', '2018-04-01', 30 )
insert into @t2
values
('A', 'AA', '2018-01-01', 20 ),
('A', 'AA', '2018-02-01', 10 ),
('A', 'AA', '2018-03-01', 10 )
SELECT
code1
,code2
,date1
,date2
,amount1
,amount2
FROM (
SELECT code1, code2 FROM @t1
INTERSECT
SELECT code1, code2 FROM @t2
) t0
CROSS APPLY (
SELECT
date1, date2, amount1, amount2
FROM @t1 t1
FULL OUTER JOIN @t2 t2 ON t1.Code1 = t2.Code1 and t1.Code2 = t2.Code2 and date1 = date2
WHERE
t0.code1 = isnull(t1.Code1, t2.code1)
and t0.code2 = isnull(t1.Code2, t2.code2)
) tt
ORDER BY
date1, date2
答案 2 :(得分:0)
我建议的解决方案涉及使用code2
运算符进行完全联接和另一个联接到派生表,该派生表包含两个表中存在的intersect
和DECLARE @T1 AS TABLE
(
Code1 char(1),
Code2 char(2),
Date1 char(6),
Amount1 int
)
DECLARE @T2 AS TABLE
(
Code1 char(1),
Code2 char(2),
Date2 char(6),
Amount2 int
)
INSERT INTO @T1 (Code1, Code2, Date1, Amount1) VALUES
('A', 'AA', '201802', 100)
,('A', 'AA', '201803', 50)
,('A', 'AA', '201804', 30)
,('B', 'AA', '201802', 30); -- Note: Added to the original sample data
INSERT INTO @T2 (Code1, Code2, Date2, Amount2) VALUES
('A', 'AA', '201801', 20)
,('A', 'AA', '201802', 10)
,('A', 'AA', '201803', 10)
,('A', 'AB', '201802', 10); -- Note: Added to the original sample data
的所有组合。 / p>
首先,创建并填充示例数据(请在您将来的问题中为我们保存此步骤):
SELECT ISNULL(T1.Code1, T2.Code1) As Code1,
ISNULL(T1.Code2, T2.Code2) As Code2,
Date1, Date2, Amount1, Amount2
FROM @T1 As T1
FULL JOIN @T2 As T2
ON T1.Code1 = T2.Code1
AND T1.Code2 = T2.Code2
AND T1.Date1 = T2.Date2
-- Remove this next join if you want to get rows where codes don't match
JOIN (
SELECT Code1, Code2
FROM @T1
INTERSECT
SELECT Code1, Code2
FROM @T2
) As CommonCodes
ON CommonCodes.Code1 = ISNULL(T1.Code1, T2.Code1)
AND CommonCodes.Code2 = ISNULL(T1.Code2, T2.Code2)
ORDER BY Date1
查询:
Code1 Code2 Date1 Date2 Amount1 Amount2
A AA NULL 201801 NULL 20
A AA 201802 201802 100 10
A AA 201803 201803 50 10
A AA 201804 NULL 30 NULL
结果:
{{1}}