如下面的两个查询所示,我们发现它们都运行良好。然后我很困惑为什么我们应该使用 BETWEEN 因为我发现 BETWEEN 在不同数据库中的行为与w3school中的不同
SELECT *
FROM employees
WHERE salary BETWEEN 5000 AND 15000;
SELECT *
FROM employees
WHERE salary >= 5000
AND salary <= 15000;
如下面的两个查询所示,我们发现它们都运行良好。然后我很困惑为什么我们应该使用 BETWEEN 因为我发现 BETWEEN 在不同数据库中的行为与w3school中的不同
SELECT *
FROM employees
WHERE salary BETWEEN 5000 AND 15000;
SELECT *
FROM employees
WHERE salary >= 5000
AND salary <= 15000;
BETWEEN
可以帮助避免不必要的重新计算表达式:
SELECT AVG(RAND(20091225) BETWEEN 0.2 AND 0.4)
FROM t_source;
---
0.1998
SELECT AVG(RAND(20091225) >= 0.2 AND RAND(20091225) <= 0.4)
FROM t_source;
---
0.3199
t_source
只是一个带有1,000,000
记录的虚拟表。
当然,这可以使用子查询来解决,但MySQL
效率较低。
当然,BETWEEN
更具可读性。在查询中使用它需要3
很长时间才能永远记住语法。
在SQL Server
andMySQL
中,LIKE
针对非前导常量'%'
也是一对>=
and的简写<
:
SET SHOWPLAN_TEXT ON
GO
SELECT *
FROM master
WHERE name LIKE 'string%'
GO
SET SHOWPLAN_TEXT OFF
GO
|--Index Seek(OBJECT:([test].[dbo].[master].[ix_name_desc]), SEEK:([test].[dbo].[master].[name] < 'strinH' AND [test].[dbo].[master].[name] >= 'string'), WHERE:([test].[dbo].[master].[name] like 'string%') ORDERED FORWARD)
但是,LIKE
语法更清晰。
当比较的表达式是一个复杂的计算而不仅仅是一个简单的列时,使用 BETWEEN 有额外的优点;它节省了写出那个复杂的表达式两次。
带有“之间”的版本更易于阅读。如果我要使用第二个版本,我可能会把它写成
5000 <= salary and salary <= 15000
出于同样的原因。
T-SQL 中的 BETWEEN 支持 NOT 运算符,因此您可以使用类似的结构
WHERE salary not between 5000 AND 15000;
在我看来,这对人类来说更清楚
WHERE salary < 5000 OR salary > 15000;
最后,如果您只键入一次列名,那么出错的机会就会减少
就个人而言,我不会使用BETWEEN
,只是因为在您给定的示例中,似乎没有明确定义它是否应该包含或排除用于限制条件的值:
SELECT *
FROM emplyees
WHERE salary between 5000 AND 15000;
范围可以包括 5000 和 15000,也可以排除它们。
从语法上讲,我认为它应该排除它们,因为值本身不在 给定的数字之间。但我的观点恰恰是这样,而使用诸如此类的运算符>=
是非常具体的。并且不太可能在数据库之间或相同的增量/版本之间进行更改。
针对 Pavel 和 Jonathan 的评论进行了编辑。
正如 Pavel 所指出的,ANSI SQL (http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt)早在 1992 年,要求端点应在返回的日期内考虑,相当于X >= lower_bound AND X <= upper_bound
:
8.3
Function Specify a range comparison. Format <between predicate> ::= <row value constructor> [ NOT ] BETWEEN <row value constructor> AND <row value constructor> Syntax Rules 1) The three <row value constructor>s shall be of the same degree. 2) Let respective values be values with the same ordinal position in the two <row value constructor>s. 3) The data types of the respective values of the three <row value constructor>s shall be comparable. 4) Let X, Y, and Z be the first, second, and third <row value con- structor>s, respectively. 5) "X NOT BETWEEN Y AND Z" is equivalent to "NOT ( X BETWEEN Y AND Z )". 6) "X BETWEEN Y AND Z" is equivalent to "X>=Y AND X<=Z".
我投票给@Quassnoi - 正确性是一个巨大的胜利。
我通常发现文字比 <、<=、>、>=、!= 等语法符号更有用。是的,我们需要(更好、更准确)的结果。至少我摆脱了视觉上误解和还原符号含义的可能性。如果您使用 <= 并从您的选择查询中感觉到逻辑上不正确的输出,您可能会徘徊一段时间,并且只能得出您确实写了 <= 代替 >= [视觉错误解释?] 的结论。希望我清楚。
我们不是在缩短代码(同时让它看起来更高级),这意味着更简洁和易于维护吗?
SELECT *
FROM emplyees
WHERE salary between 5000 AND 15000;
SELECT *
FROM emplyees
WHERE salary >= 5000 AND salary <= 15000;
第一个查询只使用 10 个单词,第二个使用 12 个!
如果端点是包容性的,那么BETWEEN
是首选语法。
对列的引用越少,意味着当事情发生变化时需要更新的地方就越少。这是工程原理,更少的东西意味着更少的东西可以破坏。
这也意味着有人为包括 OR 之类的东西放错括号的可能性较小。IE:
WHERE salary BETWEEN 5000 AND (15000
OR ...)
...如果将括号放在 BETWEEN 语句的 AND 部分周围,则会出现错误。相对:
WHERE salary >= 5000
AND (salary <= 15000
OR ...)
...只有当有人查看从查询返回的数据时,您才会知道存在问题。
从语义上讲,这两个表达式具有相同的结果。
但是,BETWEEN
是单个谓词,而不是两个比较谓词与AND
. 根据您的 RDBMS 提供的优化器,单个谓词可能比两个谓词更容易优化。
尽管我希望大多数现代 RDBMS 实现应该对这两个表达式进行相同的优化。
更糟糕的是
SELECT id FROM entries
WHERE
(SELECT COUNT(id) FROM anothertable WHERE something LEFT JOIN something ON...)
BETWEEN entries.max AND entries.min;
用你的语法重写这个而不使用临时存储。
我最好使用第二个,因为你总是知道它是 <= 还是 <
在 SQL 中,我同意这BETWEEN
大部分是不必要的,并且可以在语法上用5000 <= salary AND salary <= 15000
. 它也是有限的;我经常想应用一个包容性的下限和一个独占的上限:@start <= when AND when < @end
,你不能用BETWEEN
.
OTOH,如果要测试的值是复杂表达式的结果,则 BETWEEN 很方便。
如果 SQL 和其他语言能效仿 Python 使用正确的数学符号,那就太好了:5000 <= salary <= 15000
.
一个能让你的代码更具可读性的小技巧:使用 < 和 <= 优先于 > 和 >=。