2015-07-01 96 views
2

我有如下的情景:条件加入SQL服务器

源1

Column1 
Column2 

源2

Column1 
Column2 

输出 - 我需要一个视图;

Source1中Column2不为空的所有记录必须位于视图中。

其中Column2为空的Source1中的所有记录必须与Source2(在Column1上,两个表之间的引用)连接。无论哪里发现匹配,Source2的Column2也应包含在视图中。

任何指针请..

+0

我们在谈论哪种SQL?一般来说,你可以做一个'LEFT OUTER JOIN'来完成你正在寻找的东西。 – willaien

回答

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

因此,要回顾:仅包括其中填充Source1.Column2线,并包括列2 Source2以及如果这也是填充?

你在找什么是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 
1

使用外连接Source1Source2之间。

该规范有点宽松。您是否希望将Column2Source2作为单独的(第三)列返回,或者是否希望第二列中的值取代Column2的“空”值?Source1

什么是Column2的数据类型Source1Source2?那是字符类型,数字,日期时间吗?

你如何定义“空”?对于字符类型,是否包含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 

...将返回符合规范要求结果的查询可以改变/调整以适应更严格(更精确)的规格ication。

编辑

哎呀。

上面的示例查询基于另一个假设:这是针对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额外内径柱

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) 

注意,这个例子包括source1source2的第1列中的“重复”值,并显示返回的结果。 (包含s_idt_id列是为了帮助破译返回的行。)