2015-07-01 125 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列是爲了幫助破譯返回的行。)