oracle 带日期筛选的SQL JOIN最佳实践

btxsgosb  于 2022-11-03  发布在  Oracle
关注(0)|答案(1)|浏览(191)

我想在Oracle sql中完成以下任务:
仅返回Table1中开始日期和结束日期跨越Table2中开始日期和结束日期的行。

Table 2:
 ------------------------------------
| uid | startdate |enddate | typenum |
 ------------------------------------
| 123 | 09/1/22   | 09/3/22 | 25     |

应返回表1中与表2的开始日期和结束日期重叠的任何行。例如:

Table 1 - qualified rows:
 ------------------------------------
| uid | startdate |enddate | typenum |
 ------------------------------------
| 123 | 09/1/22   | 09/3/22 | 10    |        
| 123 | 09/2/22   | 09/6/22 | 30    |  
| 123 | 08/28/22   | 08/30/22 | 25    |
| 123 | 09/4/22   | 09/5/22 | 25    |

Table 1 - disqualified rows:
 ------------------------------------
| uid | startdate |enddate | typenum |
 ------------------------------------
| 123 | 09/1/22   | 09/3/22 | 25     |        
| 123 | 09/2/22   | 09/6/22 | 25     |  
| 123 | 08/30/22   | 09/2/22 | 25    |
| 123 | 08/30/22   | 09/7/22 | 25    |

此查询可以工作,但是否可以进一步优化和清理?

Select * From Table1 T1
INNER JOIN Table2  T2 ON T1.uid = T2.uid
AND T1.typenum = 25
AND ( 
    ( T1.startdate BETWEEN T2.startdate AND T2.endate OR T1.endate BETWEEN T2.startdate AND 
    T2.endate )
    OR ( T1.startdate >  T2.startdate AND T1.endate < T2.endate )
    OR ( T1.startdate <  T2.startdate AND T1.endate > T2.endate )
    )
6jygbczu

6jygbczu1#

要测试 * 不 * 相交的跨距,只有两个选项。


* ---*

     *---*

     *---*

* ---*

让我们写一个测试,如果一个事件在另一个事件之后开始,它们就不会相交。

t1.end < t2.start OR
t2.end < t1.start

为了测试交集,我们取反它。

NOT(
  t1.end < t2.start OR
  t2.end < t1.start
)

我们可以应用De Morgan's Law来去掉not。

t1.end >= t2.start AND
t2.end >= t1.start

让我们看看所有的可能性。一个跨度的结束总是必须相同或在另一个跨度的开始之后。


* ----*     ✓
* ----*

* ----*     ✓

  *----*

  *----*   ✓

* ----*

* -----*    ✓

 *---*

* -----*    ✓

 *---*

相关问题