【问题标题】:Checking if the "system" falls between two dates in SQL检查“系统”是否位于 SQL 中的两个日期之间
【发布时间】:2016-06-07 03:52:45
【问题描述】:

场景是 DEMO001 系统在 8 月 10 日至 8 月 11 日期间被某个用户预订。

START_DATE     END DATE    SYSTEM
2016-08-10     2016-08-11  DEMO001
2016-09-05     2016-09-08  DEMO001
2016-08-08     2016-08-11  DEMO013
2016-08-16     2016-08-18  DEMO017

如果其他用户在这几天之间尝试预订此系统。我们必须检查并通过 0 或 1。

我会得到一个输入参数

1) start_date as 2016-08-08 and 2016-08-15.
2) 2016-09-06 and 2016-09-07
3) 2016-08-08 and 2016-08-09

我必须编写一个 PLSQL/SQL 代码来传递 0,因为 DEMO001 介于这些开始数据和输入的结束日期之间,否则传递 1。

请帮忙。

【问题讨论】:

  • 如果两个 span 不是嵌套的,而是重叠的(在 start 之前开始,但在 end 之前不结束)呢?
  • 请在此处包含更多显示您希望实现的示例数据。
  • @Thilo:即使在那种情况下也是 0。基本上,如果任何一个输入日期介于两者之间,则用户不允许预订此系统。
  • @TimBiegeleisen:我修改了我的问题。请检查和帮助
  • 为什么要存储过程?

标签: sql oracle plsql oracle11g


【解决方案1】:

Oracle 设置

CREATE TABLE table_name ( START_DATE, END_DATE, SYSTEM ) AS
SELECT DATE '2016-08-10', DATE '2016-08-11', 'DEMO001' FROM DUAL UNION ALL
SELECT DATE '2016-09-05', DATE '2016-09-08', 'DEMO001' FROM DUAL UNION ALL
SELECT DATE '2016-08-08', DATE '2016-08-11', 'DEMO013' FROM DUAL UNION ALL
SELECT DATE '2016-08-16', DATE '2016-08-18', 'DEMO017' FROM DUAL;

查询

使用绑定变量 :start_date:end_date 作为输入:

SELECT system,
       MIN(
         CASE
         WHEN :end_date < start_date OR :start_date > end_date
         THEN 1
         ELSE 0
         END
       ) AS can_book
FROM   table_name
GROUP BY system;

输出

对于输入 :start_date = DATE '2016-08-08':end_date = DATE '2016-08-15'

SYSTEM    CAN_BOOK
------- ----------
DEMO001          0 
DEMO013          0 
DEMO017          1 

对于输入 :start_date = DATE '2016-09-06':end_date = DATE '2016-09-07'

SYSTEM    CAN_BOOK
------- ----------
DEMO001          0 
DEMO013          1 
DEMO017          1 

对于输入 :start_date = DATE '2016-08-08':end_date = DATE '2016-08-09'

SYSTEM    CAN_BOOK
------- ----------
DEMO001          1 
DEMO013          0 
DEMO017          1 

【讨论】:

  • 成功了 :) 完美
【解决方案2】:

根据您的要求,如果开始日期或结束日期介于给定记录之间,您希望拒绝预订。您可以为此使用 CASE 表达式。我已将 2016-08-082016-08-15 硬编码为您使用的开始日期和结束日期。

SELECT SYSTEM,
    CASE WHEN (DATE '2016-09-06' < START_DATE AND DATE '2016-09-07' < START_DATE) OR
              (DATE '2016-09-06' > END_DATE AND DATE '2016-09-07' > END_DATE)
         THEN 1
         ELSE 0
    END AS allowBooking
FROM yourTable

这是一个 SQL Fiddle 链接,显示了输入范围为 2016-08-082016-08-09 的查询。它清楚地表明除了DEMO013 之外的所有预订都是可能的。我使用了 MySQL,但从 MySQL 到 Oracle 的逻辑不应该改变,反之亦然。

SQLFiddle

【讨论】:

  • 在一种情况下失败了。我在表格中添加了第二行和另一个输入。 @蒂姆
  • 我不明白为什么会失败。
  • (2016-09-05>= '2016-09-06' AND '2016-09-05'= '2016-09-06 和 '2016-09-08'
  • 我转而使用BETWEEN,因为您在上面的评论中写了WHERE 子句很难阅读。它现在应该可以工作了。
  • 如果在第一个条件之间使用它会失败。那就是我对写一个通用条件@Tim感到困惑。
猜你喜欢
  • 2015-05-30
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
  • 2013-05-08
相关资源
最近更新 更多