【问题标题】:Return overlapping date records in SQL在 SQL 中返回重叠的日期记录
【发布时间】:2015-09-15 16:11:33
【问题描述】:

我使用以下查询来获取 SQL 中的重叠记录:

SELECT QUOTE_ID,FUNCTION_ID,FUNCTION_DT,FUNC_SPACE_ID,FN_START_TIME,FN_END_TIME,DATE_AUTH_LEVEL
FROM R_13_ALL_RESERVED A 
WHERE 
    A.FUNC_SPACE_ID = '401-ZFU-52' 
AND A.FUNCTION_DT = TO_DATE('09/03/2015','MM/DD/YYYY')
AND EXISTS ( SELECT 'X'
             FROM R_13_ALL_RESERVED B
             WHERE A.PROPERTY = B.PROPERTY
               AND A.FUNCTION_DT = B.FUNCTION_DT 
               AND A.FUNCTION_ID <> B.FUNCTION_ID
               AND ( (    A.FN_START_TIME > B.FN_START_TIME 
                      AND A.FN_START_TIME < B.FN_END_TIME) 
                  OR (    B.FN_START_TIME > A.FN_START_TIME 
                      AND B.FN_START_TIME < A.FN_END_TIME)
                  OR (    A.FN_START_TIME = B.FN_START_TIME 
                      AND A.FN_END_TIME = B.FN_END_TIME)
                   )
           )

但即使日期不重叠,它仍会将记录返回为重叠。

我在这里遗漏了一些东西?

另外,如果日期记录重叠,我需要将function_id 记录的计数与DATE_AUTH_LEVEL 进行比较,如果2 个function_id 记录重叠并且function_id 的计数为2,DATE_AUTH_LEVEL 为1,这样的记录应该在结果集中。

请在 SQLFiddle 中查找数据集 http://sqlfiddle.com/#!9/95874/1

期望的输出: SQL 应该返回重叠的 FN_START_TIME 和 FN_END_TIME 的 function_space_id 和它的 function_dt

在提供的示例中,函数空间 id '401-ZFU-12' 和 function_dt 'August, 15 2015' 的行 5 和 6 重叠,其他所有不重叠

【问题讨论】:

  • 您好,下次尝试提供SqlFiddle,这样我们可以更好地理解问题并更快地给您答案——也请阅读How to ask和How to create a Minimal, Complete, and Verifiable example.
  • 我不明白为什么它会显示错误的重叠,但最好的重叠检查只是(a.start_time &lt; b.end_time and b.start_time &lt; a.end_time) - 请参阅this explanation
  • 您应该同时提供样本数据和期望输出
  • 我在使用 SQL fiddle 时遇到了一些困难,我会尽快提供详细信息
  • @user2999377 你为 MySql 创建一个小提琴而不是 Oracle 尝试 this fiddle 代替

标签: sql oracle


【解决方案1】:

用于检测两个范围重叠的最简单的谓词(where 子句条件)是将第一个范围的开始与第二个范围的结束进行比较,并将第二个范围的开始与第一个范围的结束进行比较:

WHERE R1.Start_Date <= R2.End_Date
  AND R2.Start_Date <= R1.End_Date

正如您所见,这两个不等式中的每一个都从不同的记录(R1 和 R2,然后是 R2 和 R1)中查看开始和结束值,剩下的就是添加将关联记录的条件,并确保您没有将一行与自身进行比较因此,如果您想查找所有具有重复日期范围的 Distinct_ID 的 Common_ID:

select *
  from Your_Table R1
 where exists (select 1 from Your_Table R2
                where R1.Common_ID = R2.Common_ID
                  and R1.Distinct_ID <> R2.Distinct_ID
                  and R1.Start_Date <= R2.End_Date
                  and R2.Start_Date <= R1.End_Date)

如果没有可使用的 Distinct_ID,您可以使用R1.rowid &lt;&gt; R2.rowid 代替R1.Distinct_ID &lt;&gt; R2.Distinct_ID

【讨论】:

    【解决方案2】:

    这是解决问题的方法。

    我的第一个怀疑是您的 exists 子句的结果太宽泛,因此意外地返回了外部子句中匹配的每条记录的行。可能有一些行不在所需的日期或 spaceid 上,它们与您的内部标准共享其间隔的一个组成部分。

    • 检查内部 select 语句(exists 子句中的语句)的结果以获取示例行,将所有 'A' 别名值与来自的实际值交换返回的行之一是您不希望收到的。

    • 此外,您可以在执行配置文件中检查我认为的 semi join 以查看连接条件是什么。如果您希望它被 '401-ZFU-52' 的 'FUNC_SPACE_ID' 常量过滤,您会发现它不是。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      相关资源
      最近更新 更多