2013-08-23 57 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进行确认。