我使用以下查询来获取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;而所有其他都没有重叠
答案 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'的常量进行过滤,您会发现它不是。