假设我们在SQL数据库中有两个表(我使用的是PostgreSQL,以防答案取决于数据库):
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
首选哪种方式?是否存在性能差异?
答案 0 :(得分:4)
好吧,WHERE
子句会过滤结果。 ON
只定义了表连接在一起的方式。在你的例子中没有区别。
但请看一下以下内容:
CREATE TABLE testA
(
id integer,
checked boolean
)
CREATE TABLE testB
(
id integer,
testA_id integer,
checked boolean
)
如您所见,我在TestB中添加了一个选中的列。
TableA中可能有行在TableB中没有行像以下数据一样:
<强>种皮强>
ID|checked
1|true
2|true
3|false
<强> TESTB 强>
ID|testA_id|checked
1|1|true
2|1|false
3|3|true
正如您所看到的,TestA id = 2
没有TestB现在,我们假设您要显示所有 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
返回TableA的ID 1,2和3,如果有一个已检查的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,因为我们过滤结果只显示已检查过TableB的结果。
答案 1 :(得分:1)
没有性能差异,优化器会处理它,因此两个查询实际上是相同的。您可以在查询中使用EXPLAIN
进行确认。