【问题标题】:SQL Select if DateTime is between some Time intervalSQL Select 如果 DateTime 在某个时间间隔之间
【发布时间】:2018-10-21 20:27:44
【问题描述】:

我有桌子 T1:

ID  SCHEDULE
1   2018-05-12 14:00:00

我有桌子 T2

 SCHEDULESTART       SCHEDULEEND
 09:00                  17:00

我需要从 T1 表中进行 SELECT。

我想从 T1 中获取所有行,其中 SCHEDULE 字段中的 TIME 介于时间段(第二个表中的 START 和 END)之间。

我在一些 IBM 应用程序中工作,其中只能在第一个表 T1 的 WHERE 子句之后以 SQL 语句开头。

所以查询(很遗憾)必须始终以"SELECT * FROM T1 WHERE..." 开头 这无法更改(请记住这一点)。

这意味着我不能在 "FROM T1" 部分之后使用一些 JOIN 或 UNION ALL 语句,因为我只能在 WHERE 子句之后开始编写 SQL 查询。

对于这个例子,可以有这样的语句:

select TIME(SCHEDULE) from T1
where  TIME(SCHEDULE)>=(SELECT SCHEDULESTART FROM T2 ) 
AND    TIME(SCHEDULE)<=(SELECT SCHEDULEEND FROM T2)

它会返回正确的结果。

但是, 例如,如果 SCHEDULE 是 2018-05-12 23:00:00SCHEDULESTART is 22:00:00SCHEDULEEND is 03:00:00,则此查询将不起作用(这是合乎逻辑的,因为时间是在夜间和从第一天切换到第二天的时间段内)! T2表中可以计算的最大时间段为24小时时间段(仅1天)。

应该如何准确地定义 SQL 查询以涵盖所有情况? 谢谢,

【问题讨论】:

    标签: sql datetime select time db2


    【解决方案1】:

    试试这个:

    where 
    EXISTS (
            SELECT 
                1
            FROM 
                T2
            WHERE 
                ( 
                    SCHEDULESTART <= SCHEDULEEND 
                AND
                    TIME(T1.SCHEDULE) BETWEEN SCHEDULESTART AND SCHEDULEEND
                )
            OR
                (
                    SCHEDULESTART > SCHEDULEEND AND
                    (
                        TIME(T1.SCHEDULE) NOT BETWEEN SCHEDULEEND AND SCHEDULESTART
                    ) 
                    OR 
                        TIME(T1.SCHEDULE) = SCHEDULESTART 
                    OR 
                        TIME(T1.SCHEDULE) = SCHEDULEEND
                )
            );
    

    【讨论】:

    • 我认为括号错误。您认为这现在涵盖了所有案例吗?
    • 已更新。我认为这将涵盖所有场景。但不要犹豫,自己测试一下。
    【解决方案2】:

    这是一个复杂的例子。我会把你的版本写成:

    where EXISTS (SELECT 1 FROM T2 WHERE TIME(T1.SCHEDULE) BETWEEN SCHEDULESTART AND SCHEDULEEND)
    

    然后您可以将其修改为:

    where EXISTS (SELECT 1
                  FROM T2
                  WHERE (SCHEDULESTART <= SCHEDULEEND AND
                         TIME(T1.SCHEDULE) BETWEEN SCHEDULESTART SCHEDULEEND)
                        ) OR
                        (SCHEDULESTART > SCHEDULEEND AND
                         TIME(T1.SCHEDULE) NOT BETWEEN SCHEDULESTART AND SCHEDULEEND)
                        )
                  );
    

    【讨论】:

    • 嗨,戈登。您是否在第一个 BETWEEN 语句中缺少 AND?.. 这是否涵盖了所有可能的情况?我希望你明白我的问题是什么?提前谢谢你
    • 我也认为你的第二个例子中有一些括号错误?
    • 考虑 EDGE 案例场景......因为您使用的是NOT BETWEEN,所以不会考虑SCHEDULESTARTSCHEDULEEND。因此,如果 T1.SCHEDULE22:00 它将为 NOT BETWEEN 22:00 AND 03:00 返回 false
    • 嗨,拉胡尔,戈登。我也注意到了一些错误。如果 DATETIME 是 2018-05-12 23:30:00 并且 START 是 23:31 并且 END 是 03:00 这个查询返回结果虽然它不应该返回它!!!因此,这似乎无法正常工作。
    • @RahulJain 。 . .我认为“边缘”案例的问题并不明确。此解决方案中的逻辑可以很容易地适应包括或不包括端点。
    猜你喜欢
    • 1970-01-01
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多