SQL选择查询

时间:2010-04-18 00:48:52

标签: sql

哪个更好,有什么区别?

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

5 个答案:

答案 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过去比inexists运行得更快,在某些情况下可能仍会运行得更快。 但由于结果可能不同,因此您需要确保数据支持从inexists转换为join