16

如下面的两个查询所示,我们发现它们都运行良好。然后我很困惑为什么我们应该使用 BETWEEN 因为我发现 BETWEEN 在不同数据库中的行为与w3school中的不同

SELECT *
FROM employees
WHERE salary BETWEEN 5000 AND 15000;

SELECT *
FROM employees
WHERE salary >= 5000
AND salary <= 15000;
4

11 回答 11

32

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语法更清晰。

于 2009-12-25T09:17:12.197 回答
16

当比较的表达式是一个复杂的计算而不仅仅是一个简单的列时,使用 BETWEEN 有额外的优点;它节省了写出那个复杂的表达式两次。

于 2009-12-25T09:07:48.340 回答
5

带有“之间”的版本更易于阅读。如果我要使用第二个版本,我可能会把它写成

5000 <= salary and salary <= 15000

出于同样的原因。

于 2009-12-25T08:51:53.450 回答
5

T-SQL 中的 BETWEEN 支持 NOT 运算符,因此您可以使用类似的结构

WHERE salary not between 5000 AND 15000; 

在我看来,这对人类来说更清楚

WHERE salary < 5000 OR salary > 15000;

最后,如果您只键入一次列名,那么出错的机会就会减少

于 2009-12-25T09:06:38.170 回答
2

就个人而言,我不会使用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".
于 2009-12-25T08:50:04.957 回答
2

我投票给@Quassnoi - 正确性是一个巨大的胜利。

我通常发现文字比 <、<=、>、>=、!= 等语法符号更有用。是的,我们需要(更好、更准确)的结果。至少我摆脱了视觉上误解和还原符号含义的可能性。如果您使用 <= 并从您的选择查询中感觉到逻辑上不正确的输出,您可能会徘徊一段时间,并且只能得出您确实写了 <= 代替 >= [视觉错误解释?] 的结论。希望我清楚。

我们不是在缩短代码(同时让它看起来更高级),这意味着更简洁和易于维护吗?

SELECT * 
FROM emplyees 
WHERE salary between 5000 AND 15000; 



SELECT * 
FROM emplyees 
WHERE salary >= 5000 AND salary <= 15000; 

第一个查询只使用 10 个单词,第二个使用 12 个!

于 2009-12-25T09:34:06.237 回答
1

如果端点是包容性的,那么BETWEEN是首选语法。

对列的引用越少,意味着当事情发生变化时需要更新的地方就越少。这是工程原理,更少的东西意味着更少的东西可以破坏。

这也意味着有人为包括 OR 之类的东西放错括号的可能性较小。IE:

WHERE salary BETWEEN 5000 AND (15000
  OR ...)

...如果将括号放在 BETWEEN 语句的 AND 部分周围,则会出现错误。相对:

WHERE salary >= 5000
 AND (salary <= 15000
  OR ...)

...只有当有人查看从查询返回的数据时,您才会知道存在问题。

于 2009-12-25T08:59:56.570 回答
0

从语义上讲,这两个表达式具有相同的结果。

但是,BETWEEN是单个谓词,而不是两个比较谓词与AND. 根据您的 RDBMS 提供的优化器,单个谓词可能比两个谓词更容易优化。

尽管我希望大多数现代 RDBMS 实现应该对这两个表达式进行相同的优化。

于 2009-12-25T09:05:39.357 回答
0

更糟糕的是

  SELECT id FROM entries 
  WHERE 
     (SELECT COUNT(id) FROM anothertable WHERE something LEFT JOIN something ON...) 
     BETWEEN entries.max AND entries.min;

用你的语法重写这个而不使用临时存储。

于 2010-02-01T11:50:28.207 回答
-1

我最好使用第二个,因为你总是知道它是 <= 还是 <

于 2009-12-25T08:49:25.327 回答
-1

在 SQL 中,我同意这BETWEEN大部分是不必要的,并且可以在语法上用5000 <= salary AND salary <= 15000. 它也是有限的;我经常想应用一个包容性的下限和一个独占的上限:@start <= when AND when < @end,你不能用BETWEEN.

OTOH,如果要测试的值是复杂表达式的结果,则 BETWEEN 很方便。

如果 SQL 和其他语言能效仿 Python 使用正确的数学符号,那就太好了:5000 <= salary <= 15000.

一个能让你的代码更具可读性的小技巧:使用 < 和 <= 优先于 > 和 >=。

于 2009-12-25T08:51:03.957 回答