【问题标题】:Check if a time is between two times (time DataType)检查时间是否在两次之间(时间数据类型)
【发布时间】:2020-12-18 01:45:34
【问题描述】:

我有一个表格,其中有一列“已创建”作为日期时间。

我正在尝试查询 Created 值的时间是否介于两次之间。

第一行的 Created datetime 是“2013-07-01 00:00:00.000”(午夜),我正在尝试查询时间在晚上 11 点到早上 7 点之间的项目。

select *
from MyTable
where CAST(Created as time) between '23:00:00' and '06:59:59'

但是没有返回任何结果。

我需要将我的时间转换为日期时间吗?

【问题讨论】:

  • 类似的问题和一个例子[这里][1] [1]:stackoverflow.com/questions/5125076/…
  • 是的,在晚上 11 点到第二天早上 7 点之间
  • 其实不必在两天之间。我有一张员工轮班表。班次 3 的开始时间为 23:00:00(晚上 11 点),结束时间为 06:59:59。这两个都存储为“时间”数据类型。
  • @t-clausen.dk:同一天的 23 点到 7 点之间没有多大意义,因为第一次晚于第二次,结果集总是空的。
  • @TimSchmelter 我不想为此争论,所以我删除了我的帖子。我的逻辑告诉我,这并不重要。在这种情况下,我是对的,但是我看到您的问题有意义的其他场景

标签: sql tsql


【解决方案1】:

我怀疑你想检查是在晚上 11 点之后 还是 早上 7 点之前:

select *
from MyTable
where CAST(Created as time) >= '23:00:00' 
   or CAST(Created as time) < '07:00:00'

【讨论】:

  • 不错的答案,但这仅适用于 SQL Server 2008 及更高版本
  • 如果您希望根据日期将项目组合在一起,您还需要非常小心。如果今天早上 6 点打包了一些东西,它将与今晚晚上 11:30 打包的其他东西组合在一起。如果您需要根据日期分组,我建议您增加一个小时或减少七个小时,然后根据需要进行计算。
  • 如果你想在 07:00 到 23:00 之间进行检查,在这种情况下,这个逻辑将不起作用,因为时间范围会有所不同,不能取决于这个
  • @George:那么情况就不同了,需要不同的代码。不过应该很容易检测到哪种情况适用。
  • @JonSkeet '谢谢十亿'
【解决方案2】:
select *
from MyTable
where CAST(Created as time) not between '07:00' and '22:59:59 997'

【讨论】:

    【解决方案3】:

    我有一个非常相似的问题,想分享我的解决方案

    鉴于此表(所有 MySQL 5.6):

    create table DailySchedule
    (
      id         int auto_increment primary key,
      start_time time not null,
      stop_time  time not null
    );
    

    选择给定时间x (hh:mm:ss) 介于开始时间和停止时间之间的所有行。包括第二天。

    注意:将NOW()替换为您喜欢的任何时间x

    SELECT id
    FROM DailySchedule
    WHERE
      (start_time < stop_time AND NOW() BETWEEN start_time AND stop_time)
      OR
      (stop_time < start_time AND NOW() < start_time AND NOW() < stop_time)
      OR
      (stop_time < start_time AND NOW() > start_time)
    

    结果

    给定

      id: 1, start_time: 10:00:00, stop_time: 15:00:00
      id: 2, start_time: 22:00:00, stop_time: 12:00:00
    
    • 带有NOW = 09:00:00的选定行:2
    • 带有NOW = 14:00:00的选定行:1
    • 带有NOW = 11:00:00的选定行:1,2
    • 带有NOW = 20:00:00 的选定行:无

    【讨论】:

      【解决方案4】:

      这也应该有效(即使在 SQL-Server 2005 中):

      SELECT *
      FROM dbo.MyTable
      WHERE Created >= DATEADD(hh,23,DATEADD(day, DATEDIFF(day, 0, Created - 1), 0))
        AND Created <  DATEADD(hh,7,DATEADD(day, DATEDIFF(day, 0, Created), 0))
      

      DEMO

      【讨论】:

        【解决方案5】:
        WITH CTE as
        (
        SELECT CAST(ShiftStart AS DATETIME) AS ShiftStart, 
        CASE WHEN ShiftStart > ShiftEnd THEN CAST(ShiftEnd AS DATETIME) +1
        ELSE CAST(ShiftEnd AS DATETIME) END AS ShiftEnd
        FROM **TABLE_NAME**
        )
        SELECT * FROM CTE
        WHERE 
        CAST('11:00:00' AS DATETIME) BETWEEN ShiftStart AND ShiftEnd -- Start of Shift
        OR CAST('23:00:00' AS DATETIME) BETWEEN ShiftStart AND ShiftEnd -- End of Shift
        

        【讨论】:

        • 在回答一个老问题时,如果您包含一些上下文来解释您的答案如何提供帮助,那么您的答案将对其他 StackOverflow 用户更有用,特别是对于已经有一个已接受答案的问题。请参阅:How do I write a good answer
        【解决方案6】:

        让我们考虑一个存储班次详细信息的表

        请检查 SQL 查询以生成表并根据输入(时间)查找时间表

        声明表变量

        declare @MyShiftTable table(MyShift int,StartTime time,EndTime time)
        

        向表变量添加值

        insert into @MyShiftTable select 1,'01:17:40.3530000','02:17:40.3530000'
        insert into @MyShiftTable select 2,'09:17:40.3530000','03:17:40.3530000'
        insert into @MyShiftTable select 3,'10:17:40.3530000','18:17:40.3530000'
        

        使用名为“Flag”的附加字段创建另一个表变量

        declare @Temp table(MyShift int,StartTime time,EndTime time,Flag int)
        

        通过交换开始和结束时间向临时表添加值

        insert into @Temp select MyShift,case when (StartTime>EndTime) then EndTime else StartTime end,case when (StartTime>EndTime) then StartTime else EndTime end,case when (StartTime>EndTime) then 1 else 0 end from @我的移位表

        创建输入变量以查找 Shift

        declare @time time=convert(time,'10:12:40.3530000')
        

        查询以找到与提供的时间相对应的班次

        select myShift from @Temp where
        (@time between StartTime and EndTime and Flag=0) 或 (@time 不在 StartTime 和 EndTime 之间且 Flag=1)

        【讨论】:

          【解决方案7】:
          select * from dbMaster oMaster  where ((CAST(GETDATE() as time)) between  (CAST(oMaster.DateFrom as time))  and  
          (CAST(oMaster.DateTo as time)))
          

          请检查一下

          【讨论】:

            【解决方案8】:

            应该是 AND 而不是 OR

            select *
            from MyTable
            where CAST(Created as time) >= '23:00:00' 
               AND CAST(Created as time) < '07:00:00'
            

            【讨论】:

            • 问题中没有OR
            • 一个时间不可能既小于7:00又大于23:00,所以AND无论如何都会返回0条记录。
            猜你喜欢
            • 2015-06-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-11-22
            相关资源
            最近更新 更多