我正在处理两个表A
和B
。表A
表示权益证券,表B
有许多关于证券的详细信息。
例如,当B.Item = 5301
时,该行指定给定安全性的价格。当B.Item = 9999
时,该行指定给定安全性的股息。我试图让价格和红利在同一行。为了实现这一点,我FULL JOINed
表B
两次到表A
。
SELECT *
FROM a a
FULL JOIN (SELECT *
FROM b) b
ON b.code = a.code
AND b.item = 3501
FULL JOIN (SELECT *
FROM b) b2
ON b2.code = a.code
AND b.item = 9999
AND b2.year_ = b.year_
AND b.freq = b2.freq
AND b2.seq = b.seq
WHERE a.code IN ( 122514 )
联接条款中的其他字段,例如Year_
,Freq
和Seq
只是确保价格和股息的日期匹配。 A.Code
只标识单个安全性。
我的问题是当我翻转完整联接的顺序时,我会得到不同数量的结果。因此,如果b.Item = 9999
出现在b.Item 2501
之前,我会得到一个结果。反过来我得到2个结果。我意识到表B
对于红利的安全性122514
没有任何条目,但有两个价格条目。
当首先指定价格时,我得到的价格和股息字段都是null
。但是,在首先指定股息时,我会为股息字段获取NULLs
,为价格字段获取nulls
。
为什么不出现两个价格条目?我希望他们在FULL JOIN
答案 0 :(得分:3)
这是因为你的第二个FULL OUTER JOIN指的是你的第一个FULL OUTER JOIN。这意味着更改它们的顺序正在对查询进行根本性更改。
这是一些伪SQL,演示了它是如何工作的:
DECLARE @a TABLE (Id INT, Name VARCHAR(50));
INSERT INTO @a VALUES (1, 'Dog Trades');
INSERT INTO @a VALUES (2, 'Cat Trades');
DECLARE @b TABLE (Id INT, ItemCode VARCHAR(1), PriceDate DATE, Price INT, DividendDate DATE, Dividend INT);
INSERT INTO @b VALUES (1, 'p', '20141001', 100, '20140101', 1000);
INSERT INTO @b VALUES (1, 'p', '20141002', 50, NULL, NULL);
INSERT INTO @b VALUES (2, 'c', '20141001', 10, '20141001', 500);
INSERT INTO @b VALUES (2, 'c', NULL, NULL, '20141002', 300);
--Same results
SELECT a.*, b1.*, b2.* FROM @a a FULL OUTER JOIN @b b1 ON b1.Id = a.Id AND b1.ItemCode = 'p' FULL OUTER JOIN @b b2 ON b2.Id = a.Id AND b2.ItemCode = 'c';
SELECT a.*, b2.*, b1.* FROM @a a FULL OUTER JOIN @b b1 ON b1.Id = a.Id AND b1.ItemCode = 'c' FULL OUTER JOIN @b b2 ON b2.Id = a.Id AND b2.ItemCode = 'p';
--Different results
SELECT a.*, b1.*, b2.* FROM @a a FULL OUTER JOIN @b b1 ON b1.Id = a.Id AND b1.ItemCode = 'p' FULL OUTER JOIN @b b2 ON b2.Id = a.Id AND b2.ItemCode = 'c' AND b2.DividendDate = b1.PriceDate;
SELECT a.*, b2.*, b1.* FROM @a a FULL OUTER JOIN @b b1 ON b1.Id = a.Id AND b1.ItemCode = 'c' FULL OUTER JOIN @b b2 ON b2.Id = a.Id AND b2.ItemCode = 'p' AND b2.DividendDate = b1.PriceDate;