哪个更好,有什么区别?
SELECT * FROM TABLE_A A WHERE A.ID IN (SELECT B.ID FROM TABLE_B B)
或
SELECT * FROM TABLE_A A, TABLE_B B WHERE A.ID = B.ID
答案 0 :(得分:9)
“最佳”方式是使用标准ANSI JOIN
语法:
SELECT (columns)
FROM TABLE_A a
INNER JOIN TABLE_B b
ON b.ID = a.ID
第一个WHERE IN
版本将经常导致相同的执行计划,但在某些平台上它可能会更慢 - 它并不总是一致的。当您开始添加更多表或创建更复杂的连接条件时,IN
查询(相当于EXISTS
)的编写和维护也将变得越来越麻烦 - 它不像实际JOIN
。
第二个以逗号分隔的语法不像JOIN
一样受支持。它适用于大多数SQL DBMS,但它不是“首选”版本,因为如果省略WHERE
子句,那么最终会得到一个交叉产品。如果您忘记写入JOIN
条件,那么您最终会遇到语法错误。由于这个安全网,JOIN
往往是首选。
答案 1 :(得分:3)
我赞成@Aaronaught的答案,但我有一些评论:
逗号样式连接语法和JOIN
语法都是ANSI。第一个是SQL-89,第二个是SQL-92。 SQL-89语法仍然是标准的一部分,以支持向后兼容性。
您能举例说明支持SQL-92语法但不支持SQL-89的RDBMS吗?我认为没有,所以“不一致支持”可能不准确。
您还可以使用JOIN
语法省略连接条件,并创建笛卡尔积。示例:SELECT ... FROM A JOIN B
有效(更正:仅在某些松散实现标准语法的品牌中才是这样,例如MySQL)。
但无论如何我同意在使用SQL-92语法时更容易发现。如果您使用SQL-89语法,最终可能会使用长WHERE
子句,并且很容易错过其中一个连接条件。
答案 2 :(得分:1)
不同之处在于,第一个子查询在某些数据库中可能较慢。第二个进行连接,在同一个查询中组合两个表。
通常,如果数据库不优化它,第二个会更快,因为使用子查询,数据库必须将子查询的结果保存在内存中。
答案 3 :(得分:1)
这两个查询会返回不同的结果。您只从第一个中的TABLE_A中选择列。
答案 4 :(得分:1)
查询X之间至少有三个不同之处:
SELECT * FROM TABLE_A A WHERE A.ID IN (SELECT B.ID FROM TABLE_B B)
和Y:
SELECT * FROM TABLE_A A, TABLE_B B WHERE A.ID = B.ID
1)正如Michas所说,列的集合将是不同的,其中查询Y将返回表A和表A中的列。 B,但查询X仅返回表A中的列。如果明确指出要返回的列,则查询X只能包含表A中的列,但查询Y将包含表B中的列。
2)行数可能不同。如果表B的ID超过与表A中的ID匹配的ID,那么将使用Query Y返回更多行,而不是X.
create table TABLE_A (ID int, st VARCHAR(10))
create table TABLE_B (ID int, st VARCHAR(10))
insert into TABLE_A values (1, 'A-a')
insert into TABLE_B values (1, 'B-a')
insert into TABLE_B values (1, 'B-b')
SELECT * FROM TABLE_A A WHERE A.ID IN (SELECT B.ID FROM TABLE_B B)
ID st
----------- ----------
1 A-a
(1 row(s) affected)
SELECT * FROM TABLE_A A, TABLE_B B WHERE A.ID = B.ID
ID st ID st
----------- ---------- ----------- ----------
1 A-a 1 B-a
1 A-a 1 B-b
(2 row(s) affected)
3)执行计划可能会有所不同,因为查询要求数据库提供不同的结果。 Inner joins
过去比in
或exists
运行得更快,在某些情况下可能仍会运行得更快。 但由于结果可能不同,因此您需要确保数据支持从in
或exists
转换为join
。