SQL:我们需要 ANY/SOME 和 ALL 关键字吗?
Posted
技术标签:
【中文标题】SQL:我们需要 ANY/SOME 和 ALL 关键字吗?【英文标题】:SQL: do we need ANY/SOME and ALL keywords? 【发布时间】:2013-07-09 09:53:05 【问题描述】:我使用 SQL(SQL Server、PostgreSQL)已有 10 多年了,但我从未在生产代码中使用过 ANY/SOME
和 ALL
关键字。我遇到的所有情况都可以使用IN
、MAX
、MIN
、EXISTS
,而且我认为它更具可读性。
例如:
-- = ANY
select * from Users as U where U.ID = ANY(select P.User_ID from Payments as P);
-- IN
select * from Users as U where U.ID IN (select P.User_ID from Payments as P);
或者
-- < ANY
select * from Users as U where U.Salary < ANY(select P.Amount from Payments as P);
-- EXISTS
select * from Users as U where EXISTS (select * from Payments as P where P.Amount > U.Salary);
使用ANY/SOME
和ALL
:
所以问题是:我错过了什么吗?是否存在ANY/SOME
和ALL
优于其他解决方案的情况?
【问题讨论】:
过去 13 年我也没用过。 我也从未使用过EXCEPT
。我坚持NOT EXISTS
我不同意这一点,我认为EXCEPT
有助于找出具有相同架构的两个表之间的差异
但是具有相同结构(在相同架构内)的表很少见。但是,当您允许视图或表格表达式时,可能会有所不同。
在 Postgres 中,ANY/ALL 语法对于搜索数组很有用,尽管我从未在普通 SQL 中使用过它。 Array searching
【参考方案1】:
我发现 ANY 和 ALL 在您不只是测试相等或不等式时非常有用。考虑
'blah' LIKE ANY (ARRAY['%lah', '%fah', '%dah']);
as used my answer to this question.
ANY
、ALL
和它们的否定可以极大地简化代码,否则这些代码需要非平凡的子查询或 CTE,在我看来,它们的使用明显不足。
考虑ANY
可以与任何运算符一起使用。它与LIKE
和~
一起使用非常方便,但可以与tsquery、数组成员测试、hstore 密钥测试等一起使用。
'a => 1, e => 2'::hstore ? ANY (ARRAY['a', 'b', 'c', 'd'])
或:
'a => 1, b => 2'::hstore ? ALL (ARRAY['a', 'b'])
如果没有ANY
或ALL
,您可能必须将它们表示为VALUES
列表上的子查询或CTE,并使用聚合来生成单个结果。当然,如果你愿意,你可以这样做,但我会坚持使用ANY
。
这里有一个真正的警告:在较旧的 Pg 版本上,如果您正在编写 ANY( SELECT ... )
,则几乎可以肯定,使用 EXISTS (SELECT 1 FROM ... WHERE ...)
在性能方面会更好。如果您正在使用优化器将ANY (...)
转换为连接的版本,那么您无需担心。如有疑问,请检查EXPLAIN
输出。
【讨论】:
+1,但是您使用的是什么 RDBMS?我已经尝试在 PostgreSQL 中使用您的查询,我能得到的最好的结果是like any (values ('%lah'), ('%fah'), ('%dah'));
SQL FIDDLE
必须是ANY(ARRAY[...])
。但是,是的,这通常非常有用。
@PeterEisentraut 哎呀,好点子。我一直认为它采用与 IN (...)
相同的简单文字列表语法
有趣 - 请您添加更多示例或链接来说明您的第二点吗?
在 ANY/ALL 表示 MAX/MIN 的情况下,一种选择比另一种有什么优势?【参考方案2】:
不,我也从未使用过ANY
、ALL
或SOME
关键字,我也从未见过它们在其他人的代码中使用过。我假设这些是残留语法,就像 SQL 中某些地方出现的各种可选关键字(例如,AS
)。
请记住,SQL 是由委员会定义的。
【讨论】:
【参考方案3】:我尝试过任何东西,但没有遗漏任何东西,只有当我使用Not
条件时,我才会养成不同类型的习惯。 exists 和 in 需要添加 not 而 any/some 只需将运算符更改为<>
。我只使用 sql server,我不确定其他软件可能会丢失一些东西
【讨论】:
以上是关于SQL:我们需要 ANY/SOME 和 ALL 关键字吗?的主要内容,如果未能解决你的问题,请参考以下文章
MySQL - This version of MySQL doesn‘t yet support ‘LIMIT & IN/ALL/ANY/SOME subquery‘
MySQL - This version of MySQL doesn‘t yet support ‘LIMIT & IN/ALL/ANY/SOME subquery‘