【问题标题】:Join Tables on the basis of start date and end dates根据开始日期和结束日期加入表
【发布时间】:2017-03-21 13:46:06
【问题描述】:

子表

    Start Date  End Date    Name   Cd   Parent1    Parent2 
     1/1/1900   3/6/2016    X      X    A           B 
     3/6/2016   12/31/4712  X-1    X    A           B 

父表 1

     Start Date      End Date    Name   Cd   Grand Parent
     1/1/1900       2/5/2015    A      A    AA
     2/5/2015       6/8/2016    A-1    A    AA
     6/8/2016       1/1/4712    A-2    A    AA

祖父表

     Start Date      End Date    Name   Cd
     1/1/1900       2/7/2015    AA     AA
     2/7/2015       1/1/4712    AA-1   AA

父表 2

     Start Date      End Date    Name   Cd
     1  1/1/1900    1/1/2012    B       B
     2  1/1/2012    3/6/2016    B-1     B

我想要基于开始/结束日期的如下结果

     Start Date C    P1   GP    P2
     1/1/1900   X    A    AA    B
     1/1/2012   X    A    AA    B-1
     2/5/2015   X    A-1  AA    B-1
     2/7/2015   X    A-1  AA-1  B-1
     3/6/2016   X-1  A-1  AA-1  B-2
     6/8/2016   X-1  A-2  AA-1  B-2
     1/1/2017   X-1  A-2  AA-1  B-3
     2/2/2017   X-1  A-2  AA-2  B-3

有人可以帮我为上述场景 TIA 编写 SQL

【问题讨论】:

    标签: sql oracle join


    【解决方案1】:

    根据提供的示例数据,这是一个解决方案。我调用了这些表:childtable、parent1、parent2、gparent

    我创建了一个名为 DATE_RANGE 的 WITH 子句来获取所需的日期列表。您也可以在子查询中执行此操作。

        WITH DATE_RANGE AS ( 
              select distinct start_date FROM childtable
              union
              select distinct start_date from parent1
              union
              select distinct start_date from gparent
              union
              select distinct start_date from parent2
          )  
          SELECT 
          D.START_DATE, 
          C.START_DATE, 
          C.NAME C,
          P1.NAME P1,
          GP.NAME GP,
          P2.NAME P2
          FROM 
          DATE_RANGE D
          JOIN CHILDTABLE C ON C.END_DATE > D.START_DATE
          JOIN PARENT1 P1 ON P1.CD = C.PARENT1 AND P1.END_DATE > D.START_DATE
          JOIN GPARENT GP ON GP.CD = P1.GPARENT AND GP.END_DATE > D.START_DATE
          JOIN PARENT2 P2 ON P2.CD = C.PARENT2 AND P2.END_DATE > D.START_DATE
          WHERE
          C.START_DATE = ( SELECT MIN(START_DATE) FROM CHILDTABLE C2
                           WHERE C2.END_DATE > D.START_DATE        )  and   
          P1.START_DATE = ( SELECT MIN(START_DATE) FROM PARENT1 P12
                                WHERE P12.END_DATE > D.START_DATE  )  and
          GP.START_DATE = ( SELECT MIN(START_DATE) FROM GPARENT GP2
                                WHERE GP2.END_DATE > D.START_DATE  )  and
          P2.START_DATE = ( SELECT MIN(START_DATE) FROM PARENT2 P22
                                WHERE P22.END_DATE > D.START_DATE  ) 
          ORDER BY D.START_DATE
          ;
    

    子查询示例:

    SELECT D.START_DATE, C.START_DATE, C.NAME C
      ,P1.NAME P1  ,GP.NAME GP  ,P2.NAME P2
      FROM 
      ( select distinct start_date FROM childtable
          union
          select distinct start_date from parent1
          union
          select distinct start_date from gparent
          union
          select distinct start_date from parent2)  D
      JOIN CHILDTABLE C ON C.END_DATE > D.START_DATE
      JOIN PARENT1 P1 ON P1.CD = C.PARENT1 AND P1.END_DATE > D.START_DATE
    ...
    

    【讨论】: