在SQL中返回重叠的日期记录

时间:2015-09-15 16:11:33

标签: sql oracle

我使用以下查询来获取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及其功能_dt

在提供的示例中,行 5和6重叠用于功能空间id&#39; 401-ZFU-12&#39;和function_dt&#39; 2015年8月15日&#39;而所有其他都没有重叠

2 个答案:

答案 0 :(得分: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 <> R2.rowid代替R1.Distinct_ID <> R2.Distinct_ID

答案 1 :(得分:0)

以下是解决问题的方法。

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

  • 检查示例行的内部select语句(exists子句中的语句)的结果,交换所有'A'别名值来自其中一行返回的实际值,您预计不会收到。

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

    < / LI>