哪个更好,有什么区别?SQL Select查询
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
哪个更好,有什么区别?SQL Select查询
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
“最佳” 的方式是使用标准的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用于指定列而不是'*'(更好的性能),我希望我可以给你另外一个+1明确指定JOIN ... – CJM 2010-04-18 01:07:35
+1,但在单独的答案中查看我的意见。 – 2010-04-18 01:38:23
这是一个很好的答案,但是以逗号分隔的语法(这是标准SQL的核心部分和此类功能可能永远不会从SQL标准中删除)的说法并不被广泛支持,这只是不真实的。我甚至会说它是CROSS JOIN语法更广泛的支持。只需编辑答案。 也考虑到这个问题,强调查询不一定会返回相同的结果(如http://stackoverflow.com/questions/2660666/sql-select-queries/2661058#2661058) – Unreason 2010-04-19 08:25:43
区别在于第一个子查询可能在某些数据库中速度较慢。第二个是连接,在同一个查询中组合两个表。
通常,如果数据库不会对其进行优化,则第二种方法会更快,因为使用子查询时数据库必须将子查询的结果保留在内存中。
我upvoted @ 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
子句,并且很容易错过其中一个加入条件。
'SELECT ... FROM A JOIN B'无效。 JOIN,没有限定默认为内部联接,并且需要ON子句。要得到一个笛卡尔积,你必须说:'SELECT ... FROM CROSS JOIN B'(可能有一些平台允许'JOIN'没有ON,但不是标准的。) – 2010-04-18 03:36:50
@Shannon:是的,再右吧。 'JOIN'必须有'ON'或'USING'子句 - *除非你使用'NATURAL'或'UNION'加入修饰符。 – 2010-04-18 04:04:35
Bill:我似乎记得回到SQL Server 2000中,如果您尝试使用SQL-89语法外连接视图,将会出现错误(“在包含外连接运算符的查询中无法指定连接的表”)。这是一个奇怪的和神秘的错误,通过切换到SQL-92连接来解决。尽管SQL-89仍然是一个标准,但我们都知道一些标准倾向于跨平台实现。 :)无论如何好点。 – Aaronaught 2010-04-18 07:37:57
这两个查询返回不同的结果。您只能从第一个TABLE_A中选择列。
有查询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说,该组列的将是不同的,其中,查询ÿ将返回表A & B中的列,但查询X只返回表A中的列。如果明确指定了您想返回的列,则查询X只能包含来自表A的列,但查询Y将包括来自表A的列le B.
2)行数可能不同。如果表B具有比ID匹配从表A中的ID越多,那么更多的行将与查询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
的转换。
+1,但重新3)取决于a.id和b.id之间的关系,你可能是对的,也可能不是;在一对一或一对一的情况下或在多对一或一对多关系的情况下,查询将最有可能产生相同的计划(查询要求相同的结果)以防一对一 - 多或多对它不会。这取决于。 – Unreason 2010-04-19 08:20:50
第二个查询会起作用吗? – 2010-04-18 00:51:24
@Mahesh Velaga:是的,从a,b'开始'是交叉连接b'的旧样式。对于'a'中的每一行,选择'b'中的所有行。所以'从a,b where a.id = b.id'等同于'从a.id = b.id'的内部连接b'# – Andomar 2010-04-18 01:02:20
@Andomar:谢谢!直到这个较旧的版本兼容哪一点? – 2010-04-18 01:11:58