我有一个场景如下:
Source1的
Column1
Column2
源2
Column1
Column2
输出 - 我需要一个视图;
Source2中Column2不为空的所有记录都必须在视图中。
Source2中Column2为空的所有记录必须与Source2连接(在Column1上,两个表之间的引用)。无论在何处找到匹配项,Source2的Column2也应包含在视图中。
请指点..
答案 0 :(得分:1)
我看到的最简单方法是使用两个查询的并集:
SELECT * FROM Source1 WHERE Column2 IS NOT NULL
UNION
SELECT S2.* FROM Source1 S1
INNER JOIN Source2 S2
ON S1.Column1 = S2.Column1
WHERE S1.Column2 IS NULL
答案 1 :(得分:1)
那么回顾一下:只包括填充了Source1.Column2的行,如果还填充了Source2,还包括Source2的Column2?
您正在寻找的是LEFT JOIN
。学习并喜欢它,因为它是整个SQL中最便捷的东西之一。
SELECT s1.Column1, s1.Column2, s2.Column2
FROM source1 s1
LEFT JOIN source2 s2 ON s1.Column1 = s2.Column1
WHERE s1.Column2 IS NOT NULL
答案 2 :(得分:1)
在Source1
和Source2
之间使用外部联接。
规格有点宽松。您是否希望Column2
中的Source2
作为单独的(第三列)列返回,或者您是否希望第二列中的值更换为Column2
的“空”值来自Source1
?
Column2
和Source1
中Source2
的数据类型是什么?是字符类型,数字,日期时间?
你如何定义“空”?对于字符类型,是否包括NULL值和零长度字符串?
此外,表之间关系的基数是一对一,一对多(哪种方式)。它是强制性的,还是可能是零?
假设您想要所有行(如果Source2
中有多行与Source1
中的行匹配,并假设您需要第三列,并假设Column2
的数据类型是字符,假设“空”表示NULL或零长度字符串(这是很多假设)......然后是这样的:
SELECT s.column1
, s.column2
, IF(IFNULL(s.column2,'')='',t.column2,'') AS t_column2
FROM source1 s
LEFT
JOIN source2 t
ON t.column1 = s.column1
AND IFNULL(s.column2,'') = ''
ORDER BY s.column1, 2, 3
...将返回符合规范的结果。可以更改/调整该查询以适应更严格(更精确)的规范。
修改强>
糟糕!
上面的示例查询基于另一个假设:这是MySQL特有的。
上述语句的语法在其他数据库中不会“起作用”。这是一个等效语句,使用更多符合ANSI标准的语法:
SELECT s.column1
, s.column2
, CASE WHEN s.column2 IS NULL OR s.column2 = ''
THEN t.column2
ELSE ''
END AS t_column2
FROM source1 s
LEFT
JOIN source2 t
ON t.column1 = s.column1
AND (s.column2 IS NULL OR s.column2 = '')
ORDER BY s.column1, s.column2
<强>后续强>
添加了一个演示行为的示例:
SQL Fiddle here: http://sqlfiddle.com/#!9/113e6/1
设置表格和示例行:
CREATE TABLE source1
( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
, column1 INT
, column2 VARCHAR(8)
);
CREATE TABLE source2
( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
, column1 INT
, column2 VARCHAR(8)
);
INSERT INTO source1 (id, column1, column2) VALUES
(1,NULL,NULL)
,(2,NULL,'foo')
,(3,113,'fee')
,(4,114,'fi')
,(5,115,'')
,(6,116,NULL)
,(7,122,'fo')
,(8,122,'fum')
;
INSERT INTO source2 (id, column1, column2) VALUES
(21,NULL,'doh')
,(22,113,'rey')
,(23,113,'mii')
,(24,114,'fah')
,(25,115,'sew')
,(26,115,'lah')
,(27,116,NULL)
,(28,116,'')
,(29,116,'tea')
,(30,116,'doh')
;
示例查询(与上面的查询相同):
SELECT s.column1
, s.column2
, IF(IFNULL(s.column2,'')='',t.column2,'') AS t_column2
FROM source1 s
LEFT
JOIN source2 t
ON t.column1 = s.column1
AND IFNULL(s.column2,'') = ''
ORDER BY s.column1, 2, 3
示例查询 - 与上面的PLUS额外ID列
相同 SELECT s.column1
, s.column2
, IF(IFNULL(s.column2,'')='',t.column2,'') AS t_column2
-- ---------------
, s.id AS s_id
, t.id AS t_id
-- ---------------
FROM source1 s
LEFT
JOIN source2 t
ON t.column1 = s.column1
AND IFNULL(s.column2,'') = ''
ORDER BY s.column1, 2, 3
返回:
column1 column2 t_column2 s_id t_id
------- ------- --------- ------ --------
(NULL) (NULL) (NULL) 1 (NULL)
(NULL) foo 2 (NULL)
113 fee 3 (NULL)
114 fi 4 (NULL)
115 lah 5 26
115 sew 5 25
116 (NULL) (NULL) 6 27
116 (NULL) 6 28
116 (NULL) doh 6 30
116 (NULL) tea 6 29
122 fo 7 (NULL)
122 fum 8 (NULL)
请注意,此示例在{1}}和source1
的第1列中包含“重复”值,并显示返回的结果。 (包含source2
和s_id
列有助于解密返回的行。)