【问题标题】:SQL, Selecting between date/timesSQL,在日期/时间之间进行选择
【发布时间】:2012-05-04 10:04:29
【问题描述】:

这适用于 (MS SQL Server 2008) 它允许用户安排其他用户的开始和结束日期/时间,而不会重叠。

我正在解决在日程安排期间不能重叠个人的业务规则。例如,如果用户 1 计划从 2012 年 1 月 1 日到 2012 年 1 月 4 日,则用户 2 应该无法提交 2012 年 1 月 2 日到 2012 年 1 月 4 日的请求。这部分已经处理好了,下面是我的SQL。

SELECT * FROM fooTable
WHERE
    Prim = 1
AND 
    Group = 10
AND
    (('2012-06-01 08:01' between startdate and enddate
   OR '2012-06-03 08:01' between startdate and enddate)
OR
   ('2012-06-01 08:01' < startdate) AND ('2012-06-03 8:01' > enddate))

我现在需要允许时间表重叠,因为新班次可以在最后一个班次结束时开始。例如,我的结束日期是 2012 年 1 月 1 日晚上 8:00 - 我应该可以安排某人在 2012 年 1 月 1 日和晚上 8:00 开始。

需要一些帮助来思考这个问题。

【问题讨论】:

  • 这通常是特定于数据库的,并且应该使用您正在使用的特定 RDBMS 进行标记 - Oracle、MySQL 等。您没有明确地转换日期,而您确实应该这样做。
  • 如果您存储开始和结束的完整日期/时间并进行比较,难道不应该使用相同的逻辑吗? 1/1/2012 20:00 的开始时间不应与 1/1/2012 20:00 的结束时间重叠

标签: sql sql-server-2008 date time between


【解决方案1】:

首先,不要使用Group 作为列名。它是每个 SQL 标准中的保留字。为了回答,我将其重命名为grp

正在尝试安排从'2012-06-01 08:00''2012-06-03 08:00' 的新班次...

INSERT INTO tbl (prim, grp, startdate, enddate)
SELECT 1, 10, '2012-06-01 08:00', '2012-06-03 08:00'
WHERE  NOT EXISTS (
    SELECT *
    FROM   tbl
    WHERE  prim = 1
    AND    grp = 10
    AND   '2012-06-03 08:00' > startdate -- not >= to allow sharing a border
    AND   '2012-06-01 08:00' < enddate   -- and not BETWEEN ... AND either
    )

注意我比较:

new_结束 &gt old_start new_开始 &lt old_end

如果您使用BETWEEN .. AND ..,您将在测试中包含转变的边界。这与使用&gt;=&lt;= 相同。您需要使用&gt;&lt; 来允许边框重叠。

好吧,试试我大大简化的语法。不确定您最初在那里拥有什么。
这是一个working demo on sqlfiddle.com 可以玩。

【讨论】:

  • 另外,考虑在数据库中有一条记录开始于 2012 年 1 月 1 日和 2012 年 1 月 7 日结束的情况 - 如果我在 12/31 提交新记录/2011 和 2012 年 1 月 8 日,它应该仍然错误地说有人已经在覆盖该时间表。我的查询中内置了该部分,这就是我有第二个 OR 语句的原因。
  • @JasonWells:我的查询就是这样做的。试试吧!它应该涵盖所有重叠的情况。如果您不能将SELECTINSERT 结合使用,请从我的回答中选择SELECT
  • 嗨 Erwin,谢谢 - 我仍然有问题 :( - pastebin.com/uRb6Zepc- 我的查询(最上面的)返回一个它应该返回的结果,而你的却没有。也许我的语法是古怪吗?
  • @JasonWells:您的链接似乎无效。我的查询逻辑应该是合理的,我已经使用它多年了。假设所有列都是NOT NULL,顺便说一句。拿一张纸并使用重叠的线条来可视化。帮助我,当我感到困惑时。你的语法做了类似的事情,但不是完全你要求的。有一些极端情况......应该很容易验证。
  • @JasonWells:该链接现在有效。您在示例中得到了 backwards(开始 - 开始,结束 - 结束)。我添加了一些可能会澄清逻辑的答案。
猜你喜欢
  • 1970-01-01
  • 2020-11-07
  • 2012-01-01
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多