SQL:介于 <= 和 >= 之间
-
06-07-2019 - |
题
在 SQL Server 2000 和 2005 中:
- 这两个有什么区别
WHERE
条款? - 我应该在哪些场景下使用哪一个?
查询1:
SELECT EventId, EventName
FROM EventMaster
WHERE EventDate BETWEEN '10/15/2009' AND '10/18/2009'
查询2:
SELECT EventId, EventName
FROM EventMaster
WHERE EventDate >='10/15/2009'
AND EventDate <='10/18/2009'
(编辑:第二个 Eventdate 最初丢失,因此查询在语法上是错误的)
解决方案
它们是相同的: BETWEEN
是问题中较长语法的简写。
使用替代的更长语法,其中 BETWEEN
不起作用,例如
Select EventId,EventName from EventMaster
where EventDate >= '10/15/2009' and EventDate < '10/18/2009'
(笔记 <
而不是 <=
在第二种情况下。)
其他提示
他们是一样的。
需要注意的一件事是,如果您将其用于 DATETIME,则结束日期的匹配将是一天的开始:
<= 20/10/2009
不等于:
<= 20/10/2009 23:59:59
(它 会 匹配 <= 20/10/2009 00:00:00.000
)
虽然 BETWEEN
易于阅读和维护,我很少推荐使用它,因为它是一个闭区间,并且正如前面提到的,这可能是日期的问题 - 即使没有时间组件。
例如,在处理每月数据时,通常会比较日期 BETWEEN first AND last
, ,但实际上这通常更容易写 dt >= first AND dt < next-first
(这也解决了时间部分问题)-自从确定 last
通常比确定要长一步 next-first
(减去一天)。
此外,另一个问题是下限和上限确实需要在 正确的顺序 (IE。 BETWEEN low AND high
).
通常情况下,没有什么区别 - BETWEEN
并非所有 RDBMS 平台都支持关键字,但如果支持,则两个查询应该相同。
由于它们是相同的,因此在速度或其他方面实际上没有区别 - 使用您认为更自然的那个。
正如@marc_s、@Cloud 等人提到的。对于封闭范围来说,它们基本上是相同的。
但是任何小数时间值都可能会导致封闭范围(大于或等于和 小于或等于)而不是半开范围(大于或等于和 少于) 具有最终值 后 最后可能的瞬间。
因此,为了避免查询应重写为:
SELECT EventId, EventName
FROM EventMaster
WHERE (EventDate >= '2009-10-15' AND
EventDate < '2009-10-19') /* <<<== 19th, not 18th */
自从 BETWEEN
不适用于半开间隔我总是仔细查看使用它的任何日期/时间查询,因为它可能是一个错误。
我认为唯一的区别是每个查询的语法糖量。BETWEEN 只是一种巧妙的表达方式,与第二个查询完全相同。
可能存在一些我不知道的 RDBMS 特定差异,但我真的不这么认为。
我有一点偏爱 BETWEEN
因为它让读者立刻明白 您正在检查一个字段的范围. 。如果表中具有相似的字段名称,则尤其如此。
比如说,如果我们的桌子上有一个 transactiondate
和一个 transitiondate
, ,如果我读到
transactiondate between ...
我立即知道测试的两端都是针对这一领域的。
如果我读
transactiondate>='2009-04-17' and transactiondate<='2009-04-22'
我必须花额外的时间来确保这两个字段相同。
此外,随着时间的推移对查询进行编辑,马虎的程序员可能会将这两个字段分开。我见过很多这样的查询
where transactiondate>='2009-04-17'
and salestype='A'
and customernumber=customer.idnumber
and transactiondate<='2009-04-22'
如果他们尝试这样做 BETWEEN
, 当然,这将是一个语法错误并及时修复。
从逻辑上来说根本没有区别。在性能方面——通常在大多数 DBMS 上——根本没有区别。
免责声明:以下所有内容都只是轶事,直接来自我的个人经历。欢迎任何愿意进行更严格的实证分析的人来执行它,如果我愿意的话,请投反对票。我还知道 SQL 是一种声明性语言,您在编写代码时不必考虑代码是如何处理的,但是,因为我珍惜我的时间,所以我会这样做。
有无限的逻辑上等价的陈述,但我会考虑三个(左右)。
情况1:标准顺序的两次比较(评估顺序固定)
A >= MinBound 且 A <= MaxBound
案例2:语法糖(评估顺序不是作者选择的)
MinBound 和 MaxBound 之间
案例3:按受过教育的顺序进行两次比较(在写入时选择的评估顺序)
A >= MinBound 且 A >= MaxBound
或者
A >= MaxBound 且 A >= MinBound
根据我的经验,案例 1 和案例 2 在性能上没有任何一致或显着的差异,因为它们不了解数据集。
然而,案例 3 可以极大地缩短执行时间。具体来说,如果您正在处理大型数据集并且碰巧有一些关于是否 A 更有可能大于 最大边界 或小于 最小限制 通过使用案例 3 并相应地排序比较,可以显着缩短执行时间。
我的一个用例是查询具有非索引日期的大型历史数据集,以获取特定时间间隔内的记录。在编写查询时,我将很好地了解在指定间隔之前或指定间隔之后是否存在更多数据,并可以相应地排序比较。根据数据集的大小、查询的复杂性以及第一次比较过滤的记录量,我的执行时间减少了一半。