减去/添加到 Where 子句时间戳条件

Posted

技术标签:

【中文标题】减去/添加到 Where 子句时间戳条件【英文标题】:Subtracting/Adding to a Where clause timestamp condition 【发布时间】:2015-11-18 10:54:09 【问题描述】:

我试图通过将查询限制在相关时间戳前后 30 分钟来加快时间戳比较查询。这是我正在使用的格式:

Causedat
-----
11-NOV-15 10.20.58.000000000 AM
11-NOV-15 10.19.41.877000000 AM
10-NOV-15 11.01.40.000000000 AM
10-NOV-15 11.00.50.460000000 AM
05-NOV-15 01.53.30.966000000 PM
05-NOV-15 01.47.31.000000000 PM

我要做的是编写一个条件,告诉系统只在系统中查找距未来的 Causedat 日期 +-00:30:00.000000000(三十分钟)的日期或从那个时候过去。

我已经看到,例如,SYSDATE - SYSTIMESTAMP 是一个合法的计算。是否可以像这样做类似的事情:

WHERE search.date >= (Causedat = Causedat - '000000000 00:30:00.000000000')
AND   search.date <= (Causedat = Causedat + '000000000 00:30:00.000000000')

请假设我正在搜索的日期和 Causedat 的格式相同(时间戳)。

感谢您为我解决问题提供的任何启发。

【问题讨论】:

【参考方案1】:

您可以为时间戳添加间隔; you can read about datetime and interval arithmetic。有从变量到区间的转换函数,但是对于已知的固定值,您可以在此处使用an interval literal。您可以使用您拥有的完整字符串:

where search_date >= causedat - interval '000000000 00:30:00.000000000' day to second
and   search_date <= causedat + interval '000000000 00:30:00.000000000' day to second;

或者只是非零部分:

where search_date >= causedat - interval '30' minute
and   search_date <= causedat + interval '30' minute;

这些如何评估的简单演示:

select systimestamp,
  systimestamp - interval '000000000 00:30:00.000000000' day to second as minus_30,
  systimestamp + interval '000000000 00:30:00.000000000' day to second as plus_30
from dual;

SYSTIMESTAMP                        MINUS_30                            PLUS_30                           
----------------------------------- ----------------------------------- -----------------------------------
18-NOV-15 11.39.09.597473000 +00:00 18-NOV-15 11.09.09.597473000 +00:00 18-NOV-15 12.09.09.597473000 +00:00

select systimestamp,
  systimestamp - interval '30' minute as minus_30,
  systimestamp + interval '30' minute as plus_30
from dual;

SYSTIMESTAMP                        MINUS_30                            PLUS_30                           
----------------------------------- ----------------------------------- -----------------------------------
18-NOV-15 11.39.09.653809000 +00:00 18-NOV-15 11.09.09.653809000 +00:00 18-NOV-15 12.09.09.653809000 +00:00

【讨论】:

感谢您为我的问题提供的具体而广泛的解决方案。我已经接受它作为 awnsered。【参考方案2】:

使用所需的间隔值对日期时间列进行直接算术。

WHERE search.date
      BETWEEN Causedat - INTERVAL '30' MINUTE
          AND Causedat + INTERVAL '30' MINUTE

【讨论】:

您已链接到 mysql 文档。 Oracle RDBMS 没有 DATE_ADD 或 DATE_SUB。 @AlexPoole:我认为TO_DSINTERVAL 应该可以工作 @RavinderReddy - 如果你有一个变量值,那么是的;但在这种情况下,使用固定值文字就可以了。 (如果您将 30 放在单引号中使其成为文字,您的第二个版本将在 Oracle 中工作)。 您仍然需要'30' 而不是未引用的30。它必须是文字as shown in the docs;单引号不是可选的。 另外,它的分钟,不是分钟。【参考方案3】:

我刚刚回答了这个问题。我提供了一个简单的示例来说明我们如何实现这一目标。

SELECT A.DT
FROM
  ( SELECT SYSTIMESTAMP - INTERVAL '60' MINUTE AS DT FROM DUAL
  UNION
  SELECT SYSTIMESTAMP - INTERVAL '30' MINUTE AS DT FROM DUAL
  UNION
  SELECT SYSTIMESTAMP AS DT FROM DUAL
  UNION
  SELECT SYSTIMESTAMP + INTERVAL '30' MINUTE AS DT FROM DUAL
  UNION
  SELECT SYSTIMESTAMP + INTERVAL '60' MINUTE AS DT FROM DUAL
  )A
WHERE A.DT BETWEEN (SYSTIMESTAMP - INTERVAL '30' MINUTE) AND (SYSTIMESTAMP + INTERVAL '30' MINUTE);

如果这有帮助,请告诉我。

【讨论】:

以上是关于减去/添加到 Where 子句时间戳条件的主要内容,如果未能解决你的问题,请参考以下文章

Presto - where 子句中的静态日期和时间戳

续集如何查找具有多个 where 子句和时间戳的行 > NOW()

Oracle:有效地使用where子句过滤时间戳列以获取特定日期的所有记录

如何选择小于时间戳的日期和时间?

mysql: 两个字段合并,字符时间转时间戳,别名字段作为where条件查询

SQLite 中 WHERE 子句中的聚合函数