2013-07-25 48 views
0

我想參加4個表和表中的一個不具有所有匹配的ID,但我仍然需要顯示的加盟,甚至結果沒有相應ID的行。如何加入多個表,並用返回NULL值結果太

這裏就是我談論的例子:

示例表:

 

    DECLARE @Table1 TABLE (id INT PRIMARY KEY CLUSTERED, ts DateTime, tbl2_id INT, price DECIMAL(4,2), tbl3_id INT, tbl4_id INT) 

    INSERT INTO @Table1 VALUES(1, '2013-07-25 09:30:00', 10, 10.25, 1); 
    INSERT INTO @Table1 VALUES(2, '2013-07-25 10:25:00', 20, 25.25, 1); 
    INSERT INTO @Table1 VALUES(3, '2013-07-25 11:45:00', 30, 30.15, 2); 
    INSERT INTO @Table1 VALUES(4, '2013-07-25 13:31:00', 40, 80.40, 2); 

    DECLARE @Table2 TABLE (id INT PRIMARY KEY CLUSTERED, symbol VARCHAR(25), tbl1_id int) 

    INSERT INTO @Table2 VALUES(10, 'XYZ', 1); 
    INSERT INTO @Table2 VALUES(20, 'ABC', 2); 
    INSERT INTO @Table2 VALUES(30, 'RST', 3); 
    INSERT INTO @Table2 VALUES(40, 'EFG', 4); 

    DECLARE @Table3 TABLE (id INT PRIMARY KEY CLUSTERED, exch VARCHAR(25)) 

    INSERT INTO @Table3 VALUES(1, 'A'); 
    INSERT INTO @Table3 VALUES(2, 'B'); 
    INSERT INTO @Table3 VALUES(3, 'C'); 
    INSERT INTO @Table3 VALUES(4, 'D'); 

    DECLARE @Table4 TABLE (id INT PRIMARY KEY CLUSTERED, int tbl1_id, cnt INT) 

    INSERT INTO @Table4 VALUES(1, 2, 19); 
    INSERT INTO @Table4 VALUES(2, 4, 2013); 

實例查詢:

 
    SELECT tbl1.id, tbl1.ts, tbl2.symbol, IFNULL(tbl3.cnt,0) AS cnt 

    FROM TABLE1 tbl1 

    JOIN TABLE2 tbl2 
    ON tbl1.tbl2_id = tbl2.id 

    JOIN TABLE3 tbl3 
    ON tbl3.id = tbl1.tbl3_id 

    LEFT OUTER JOIN TABLE4 tbl4 
    ON tbl1.tbl4_id = tbl4.id 

    WHERE tbl1.ts BETWEEN '2013-07-25 09:30:00 AND '2013-07-25 16:00:00' 
    AND tbl1.price >= 15.00 
    LIMIT 1000; 

所以基本上我想要做的是,如果tbl4沒有tbl1_id我還是希望看到從表1的結果,但顯示0值CNT ...當我運行此查詢我收到了一堆重複條目和數據是不看的權利。

+0

嘗試連接表在表1中一次一個,看看問題出在哪裏。 –

+0

我有我的問題是與tbl4 ......我沒有在TBL1每個ID對應的ID,但我還是想顯示爲0的結果爲CNT值時,有對TBL1和tbl4 –

+0

沒有ID匹配取而代之的是左外連接做表4將包括從表4中的所有記錄和配對有比賽 – ObieMD5

回答

1

你只返回一個與聯接的左側匹配。將表4的連接更改爲正確連接,無論如何,它都將返回右側的所有記錄。我知道這是一個不適用於假數據的示例查詢。但我必須與你給我的東西一起工作。這可能不會通過複製和粘貼工作,但理論是正確的,你只需要修改它。如果你提供更詳細的信息,我會根據它進行調整。

SELECT tbl1.id, tbl1.ts, tbl2.symbol, IFNULL(tbl3.cnt,0) AS cnt 

    FROM TABLE1 tbl1 

    JOIN TABLE2 tbl2 
    ON tbl1.tbl2_id = tbl2.id 

    JOIN TABLE3 tbl3 
    ON tbl3.id = tbl1.tbl3_id 

    RIGHT JOIN TABLE4 tbl4 
    ON tbl1.tbl4_id = tbl4.id 

    WHERE tbl1.ts BETWEEN '2013-07-25 09:30:00 AND '2013-07-25 16:00:00' 
    AND tbl1.price >= 15.00 
    LIMIT 1000; 
+1

提供的樣本數據它不應該是一個'LEFT JOIN'作爲OP要求? – Akash

+0

@Akash,因爲他無論如何都想要表4中的所有記錄。因此,當所有其他人加入表4時,即使沒有記錄加入表4,也可以加入表4中的所有表。連接的右手錶給你所有的記錄,如果以前的連接中的任何連接符合條件,那麼它將連接那些與右邊的記錄(表4) – ObieMD5

0

所有在你的示例代碼首先你給SQL Server和MySQL語法的組合:

  • DECLARE TABLECLUSTERED是SQL Server功能
  • IFNULL()LIMIT是MySQL的

其次cnt列在表4中不在表3中,所以IFNULL(tbl3.cnt,0)不會飛。

第三你,當你改變tbl1.id = tbl4.tbl1_idtbl1.tbl4_id = tbl4.id不符合您的樣本數據的其餘部分加起來,因爲你沒有在你的INSERT語句無論是tbl3_id或新推出的tbl4_id值最後的編輯。現在看來tbl1_id列是不必要的。

因此恕我直言,你需要重新審視和糾正你的樣本數據。並張貼所需的輸出也可能幫助你得到你的答案。


現在,這裏是工作,並根據上次編輯之前,您的數據架構的查詢。它會成功地在MySQL和SQL Server的工作既除LIMIT部分

SELECT t1.id, t1.ts, t2.symbol, COALESCE(t4.cnt, 0) cnt 
    FROM Table1 t1 JOIN Table2 t2 
    ON t1.id = t2.tbl1_id JOIN Table3 t3 
    ON t1.tbl3_id = t3.id LEFT JOIN Table4 t4 
    ON t1.id = t4.tbl1_id 
WHERE t1.ts BETWEEN '2013-07-25 09:30:00' AND '2013-07-25 16:00:00' 
    AND t1.price >= 15.00 
LIMIT 1000 -- LIMIT will work only in MySql 

輸出:

 
| ID |       TS | SYMBOL | CNT | 
---------------------------------------------------- 
| 2 | July, 25 2013 10:25:00+0000 | ABC | 19 | 
| 3 | July, 25 2013 11:45:00+0000 | RST | 0 | 
| 4 | July, 25 2013 13:31:00+0000 | EFG | 2013 | 

這裏是SQLFiddle(MySQL的)演示
這裏是SQLFiddle( SQL Server)的演示