如何正确处理查询约束中的日期

Posted

技术标签:

【中文标题】如何正确处理查询约束中的日期【英文标题】:How to correctly handle dates in queries constraints 【发布时间】:2011-02-02 16:05:56 【问题描述】:

我目前正在使用以下查询在 2010 年 6 月完成所有检查:

select inspections.name
from inspections
where
  to_char(inspections.insp_date, 'YYYY') = 2010 and
  to_char(inspections.insp_date, 'MM') = 06;

但这感觉有点尴尬。难道没有更好的方法来做到这一点吗?看着http://infolab.stanford.edu/~ullman/fcdb/oracle/or-time.html 似乎并非如此。我正在使用 Oracle,如果它有所作为的话。

谢谢

【问题讨论】:

【参考方案1】:

我喜欢尽可能使用范围比较,因为这可以被优化器用于索引扫描:

select inspections.name
  from inspections
 where inspections.date >= DATE '2010-06-01'
   and inspections.date < DATE '2010-07-01'

【讨论】:

hmmmm,反过来,我认为它比原始查询不太清楚:( @devoured elysium :我猜这是主观的,而使用索引的能力不是:) 我认为更清楚的是,当有一个非常好的方法会使用索引时,原始的 qery 和编写的 SQL 永远不会使用索引,这是一个糟糕的主意。任何编写 SQL 的人都需要了解什么是 sargable,什么不是。清晰度(这是程序员的主观判断)不会胜过数据库查询的性能。【参考方案2】:

我同意文森特的回答,但为了完整起见,您可以简化为:

select inspections.name
from inspections
where
  to_char(inspections.insp_date, 'YYYYMM') = '201006';

这甚至可以使用索引,只要索引是:

create index x on inspections (to_char(insp_date, 'YYYYMM'));

【讨论】:

很难理解 201006 发生了什么 :( @devoured:真的吗?好吧,您可以改用“YYYY-MM”和“2010-06”。 杰弗里你没有认真对待这个!【参考方案3】:
select inspections.name
from inspections
where
  extract(year from inspections.insp_date) = 2010 and
  extract(month from inspections.insp_date) = 6;

【讨论】:

看起来不错。但它似乎是某种子查询。有效率吗?谢谢! 没有子查询,只有用于简单函数的 oracle 特定语法。 EXTRACT() 并不特定于 Oracle;这是标准 SQL。【参考方案4】:

另一种选择是

SELECT inspections.name
  FROM inspections
 WHERE TRUNC( inspections.insp_date, 'MM' ) = date '2010-06-01';

从效率的角度来看

Vincent 的解决方案可能会在 INSP_DATE 对索引使用范围扫描(假设该表有许多个月的数据,因此索引访问将是最有效的计划)。 假设表有很多个月的数据,我的查询可能会再次在 TRUNC(insp_date, 'MM') 上使用基于函数的索引。如果不同月份的行数有很大差异,则优化器的基数估计在这个基于函数的索引上可能比在直接 INSP_DATE 索引上更准确,但这在查询中不太重要这个简单。但是,如果您开始将此查询嵌套在其他地方,它可能会发挥作用。但是,如果您出于其他原因需要索引 INSP_DATE,则维护两个不同的索引可能会浪费时间和空间。 您的初始查询和 Lev 的查询都可能使用基于复合函数的索引(尽管您希望包含显式 TO_NUMBER 或与字符串而不是数字进行比较以避免隐式转换)。但是,复合索引可能是维护效率最低的(尽管我们在这里讨论的是相对较小的差异),并且在我看来是最不干净的索引替代品。

【讨论】:

如果没有完整的典型查询列表,很难预测索引效率。

以上是关于如何正确处理查询约束中的日期的主要内容,如果未能解决你的问题,请参考以下文章

查询中的日期比较:逻辑正确但结果错误

从 Excel 中查询 Access 中的常规日期字段(错误 13)

如何根据日期时间约束从另一个数据框中提取行?

如何使用POI处理Excel中的日期数据类型

SQL Server CE 中的正确日期时间格式?

您如何计算 Microsoft Access SQL 查询中的连续日期?