12

我正在尝试使用以下查询获取过去 30 天的计数 -

SELECT date_occured, COUNT(*) FROM problem
WHERE date_occured >= (CURRENT_DATE - 30)
GROUP BY date_occured;

//date_occured field is of type DATE.

基本上,在我的查询中,我试图只比较条件中的日期部分date_occured >= (CURRENT_DATE - 30),但它似乎也比较了时间。

我按如下方式尝试了 TRUNC -

TRUNC(date_occured) >= TRUNC(CURRENT_DATE - 30)

但是当运行查询时它永远不会返回。

我也试过——

SELECT date_occured, COUNT(*) FROM problem    
GROUP BY date_occured
HAVING TRUNC(date_occured) >= TRUNC(CURRENT_DATE - 30);

再一次,它永远不会回来。

如何仅比较 Oracle 中两个 DATE 值的日期部分?

4

5 回答 5

15

对于这种情况,您只需要 TRUNC 右侧:

WHERE date_occured >= TRUNC(CURRENT_DATE - 30)

为什么?因为如果 TRUNC(date_occured) 晚于 TRUNC(CURRENT_DATE - 30),那么 TRUNC(date_occured) 之后的任何时刻也必然晚于 TRUNC(CURRENT_DATE - 30)。

显然 date_occured >= TRUNC(date_occured) 总是正确的(想想看)。

逻辑上说如果 A >= B 并且 B >= C 那么它遵循 A >= C

现在替换:

  • 答:日期发生
  • B:TRUNC(日期发生)
  • C:TRUNC(CURRENT_DATE - 30)
于 2011-09-15T15:28:35.397 回答
3

我想你也想在选择部分截断:

 SELECT TRUNC(date_occured) AS short_date_occured, COUNT(*)
 FROM problem 
 WHERE date_occured >= trunc(SYSDATE- 30) 
 GROUP BY short_date_occured;
于 2011-09-15T15:33:01.520 回答
1

尝试使用 SYSDATE 与 CURRENT_DATE。Sysdate 使用服务器的本地时间,其中 CURRENT_DATE 以客户端连接的本地时间返回服务器的当前日期/时间。

于 2011-09-15T15:32:20.783 回答
1

我倾向于怀疑托尼是正确的,并且您真的只想TRUNC表达的右手边。

如果您确实想要TRUNC表达式的两边并且遇到性能问题,您可能需要一个基于函数的索引

CREATE INDEX idx_problem_trunc_dt_occured
    ON problem( trunc( date_occurred ) );

这将允许您的原始查询使用基于函数的索引。

于 2011-09-15T15:45:55.787 回答
0

这是索引友好的方法。

如果您使用 Oracle 的本机 MONTHS_BETWEEN 函数,则不需要在列上使用函数。

它返回月数的差异。天数也作为差异给出,但在精确方面,这就是我更喜欢使用 BETWEEN 子句的原因

WHERE MONTHS_BETWEEN(date_occured, CURRENT_DATE - 30) BETWEEN 0 AND 1
于 2018-12-13T17:18:09.627 回答