2013-08-23 79 views
1

假設我們在SQL數據庫中的兩個表(我在的情況下使用PostgreSQL的答案取決於數據庫):在SQL的附加條件加入

CREATE TABLE testA 
(
    id integer, 
    checked boolean 
) 

CREATE TABLE testB 
(
    id integer, 
    testA_id integer 
) 

我想要做一個選擇從testB加入了與testA並得到所有結果是checked。有兩種方法:

SELECT tA.*, tB.* 
FROM testB AS tB 
JOIN testA AS tA 
    ON (tA.id = tB.testA_id AND tA.checked) 

SELECT tA.*, tB.* 
FROM testB AS tB 
JOIN testA AS tA 
    ON tA.id = tB.testA_id 
WHERE 
    tA.checked 

哪種方式最好?有沒有性能差異?

回答

4

好吧,WHERE子句過濾結果。 ON只是定義了表格連接在一起的方式。在你的例子中,沒有區別。

但是看看下面的例子:

CREATE TABLE testA 
(
    id integer, 
    checked boolean 
) 

CREATE TABLE testB 
(
    id integer, 
    testA_id integer, 
    checked boolean 
) 

正如你可以看到我有在TESTB增加了一個檢查列。

有可能在表A行有TableB中沒有行類似下面的數據:

特斯塔

ID|checked 
1|true 
2|true 
3|false 

TESTB

ID|testA_id|checked 
1|1|true 
2|1|false 
3|3|true 

正如你可以看到有是否Test TestB for TestA id = 2

現在,讓我們假設您想要顯示ALL TestA行以及選中的TableB行(如果有)。

所以你需要一個左連接:

首例

SELECT tA.*, tB.* 
FROM testB AS tB 
LEFT JOIN testA AS tA 
    ON (tA.id = tB.testA_id AND tB.checked) 

Reults

ID|checked|ID|testA_id|checked 
1|true|1|1|true 
2|true|null|null|null 
3|false||3|3|true 

ID 1,第2和表A的3返回,如果有一個CheckB TableB行,然後我們也返回。

第二種情況

SELECT tA.*, tB.* 
FROM testB AS tB 
LEFT JOIN testA AS tA 
    ON tA.id = tB.testA_id 
WHERE 
    tB.checked 

Reults

ID|checked|ID|testA_id|checked 
1|true|1|1|true 
3|false||3|3|true 

在這種情況下,只有ID號爲1和3回,因爲我們過濾結果僅顯示有表B的那些檢查。

+1

非常真實。 [我要添加相同的](http://sqlfiddle.com/#!1/c9d0b/5)。 +1 – hims056

1

沒有性能差異,優化器負責處理它,所以這兩個查詢實際上是相同的。您可以通過在您的查詢中使用EXPLAIN進行確認。