如下面的两个查询所示,我们发现它们都运行良好。然后我很困惑为什么我们应该使用 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 ServerandMySQL中,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.
一个能让你的代码更具可读性的小技巧:使用 < 和 <= 优先于 > 和 >=。