【问题标题】:Oracle SQL statement to find the row with input time stamp between two timestamp columnsOracle SQL 语句在两个时间戳列之间查找具有输入时间戳的行
【发布时间】:2015-09-04 17:49:56
【问题描述】:

我在 Oracle DB 中有一个表

|SHIFT|     START_TIME (TIMESTAMP)     |      END_TIME (TIMESTAMP)      |
|  2  |  01-AUG-15 11.00.00.000000 PM  |  02-AUG-15 08.00.00.000000 AM  |
|  4  |  01-AUG-15 07.00.00.000000 AM  |  01-AUG-15 04.00.00.000000 PM  | 
|  3  |  01-AUG-15 02.00.00.000000 AM  |  01-AUG-15 11.00.00.000000 AM  | 
|  1  |  01-AUG-15 02.00.00.000000 PM  |  01-AUG-15 11.00.00.000000 PM  | 
|  5  |  01-AUG-15 08.30.00.000000 AM  |  01-AUG-15 05.30.00.000000 PM  | 

我希望返回与特定时间戳相对应的那些行。 运行以下查询有效:

select shift, 
  cast(start_time as time), 
  cast(end_time as time)
from mytable 
where cast('12.00.00.000000 PM' as time) 
  between cast(start_time as time) and
  cast(end_time as time);

但是,相同的查询不适用于 cast('12.00.00.000000 AM' as time) 即以下查询不起作用。它返回 0 行。我做错了什么?

select shift, 
  cast(start_time as time), 
  cast(end_time as time)
from mytable 
where cast('12.00.00.000000 AM' as time) 
  between cast(start_time as time) and
  cast(end_time as time);

我什至尝试了 start_time 和 start_time + 9hours 之间的匹配,但得到了相同的行为。

select shift,
cast(start_time as time), 
cast((start_time + numtodsinterval(9,'HOUR')) as time) 
from ata_ipd_web_shifts where cast('12.00.00.000000 PM' as time) 
BETWEEN  cast(start_time as time) AND 
cast((start_time + numtodsinterval(9,'HOUR')) as time);

那么这里的问题是什么?提取所需行的最佳方法是什么?

【问题讨论】:

  • 问题是您的时间跨度超过一天,但您只是比较一天中的时间。如果您的跨度超过一天,则需要进行不同的比较。
  • 我试图在同一天保留它,但没有用。基本上我只需要比较时间。那么如何进行这种比较呢?希望有任何帮助;我不太擅长 SQL。

标签: sql oracle timestamp


【解决方案1】:

设置您要检查 INTERVAL 的时间,并将其添加到班次的开始日期和班次的结束日期。像这样:

with d as ( SELECT 2 shift, to_timestamp('01-AUG-15 11.00.00.000000 PM') start_date, to_timestamp('02-AUG-15 08.00.00.000000 AM') end_date from dual
UNION ALL SELECT 4 shift, to_timestamp('01-AUG-15 07.00.00.000000 AM'), to_timestamp('01-AUG-15 04.00.00.000000 PM') from dual
UNION ALL SELECT 3 shift, to_timestamp('01-AUG-15 02.00.00.000000 AM'), to_timestamp('01-AUG-15 11.00.00.000000 AM') from dual
UNION ALL SELECT 1 shift, to_timestamp('01-AUG-15 02.00.00.000000 PM'), to_timestamp('01-AUG-15 11.00.00.000000 PM') from dual
UNION ALL SELECT 5 shift, to_timestamp('01-AUG-15 08.30.00.000000 AM'), to_timestamp('01-AUG-15 05.30.00.000000 PM') from dual
)
select * from d
where trunc(start_date)+TO_DSINTERVAL('0 09:00:00') between start_date and end_date
OR trunc(end_date)+TO_DSINTERVAL('0 09:00:00') between start_date and end_date

请注意,时间间隔为 24 小时制,因此(您在示例中使用的)午夜为 0 00:00:00。

【讨论】:

  • 这似乎有效! - 我仍然需要考虑它(我的 sql 生锈了)会在所有情况下尝试它,如果有任何问题我会更新此评论(或发布新评论)
  • 嗨 Matthew.. 有没有办法从现有时间戳中提取传递给 TO_DSINTERVAL 的字符串。此外,我必须从时间戳列传递输入,该列将具有不同的日期。基本上我只需要将它与时间相匹配。
  • 是的——在这种情况下不要使用 TO_DSINTERVAL。假设您拥有的现有时间戳是ts。只需将 where 子句设为 TRUNC(start_date)+(ts-trunc(ts))...。我现在不在数据库前,但这应该可以。
  • 我选择了捷径,将 shift 2 对应的行拆分为:__ |SHIFT| START_TIME (TIMESTAMP) | END_TIME (TIMESTAMP) | | 2 | 2015 年 8 月 1 日 11.00.00.000000 下午 | 2015 年 8 月 1 日 11.59.59.000000 下午 | | 2 | 15 年 8 月 1 日 12.00.00.000000 上午 | 01-AUG-15 08.00.00.000000 AM |现在我之前的查询工作正常。不过感谢您的帮助.. 学到了一些东西并可以在其他情况下使用它
猜你喜欢
  • 2023-02-14
  • 1970-01-01
  • 1970-01-01
  • 2013-10-18
  • 2014-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多