【问题标题】:ORACLE SQL Query records where date falls between minimum and maximum date from other tableORACLE SQL 查询记录的日期介于其他表的最小日期和最大日期之间
【发布时间】:2013-10-03 21:41:27
【问题描述】:

在 TABLE_A 中,每个 ID 都有一个最小 SDT 和最大 EDT。

例如:对于 ID=1000,这将是 1/09/2013 和 3/10/2013。

例如:对于 ID=1001,这将是 1/07/2013 和 3/08/2013。

预期结果将是 TABLE_B 中的所有记录,其中 TABLE_B 中的 SDT 介于 TABLE_A 中的最小 SDT 和最大 EDT 值之间。

Example Fiddle

TABLE_A

ID      SDT          EDT
------------------------------
1000    1/10/2013    3/10/2013  
1000    1/09/2013    3/09/2013   
1001    1/08/2013    3/08/2013
1001    1/07/2013    3/07/2013
1002    1/06/2013    3/06/2013

TABLE_B

ID      SDT
-----------------
1000    2/10/2013   ===> because it falls between 1/09/2013 and 3/10/2013
1000    4/09/2013   ===> because it falls between 1/09/2013 and 3/10/2013
1001    2/08/2013   ===> because it falls between 1/07/2013  and 3/08/2013
1001    4/05/2013   ==> not in result because it's not between 1/07/2013 and 3/08/2013
1002    4/06/2013   ==> also out of range, so not in results

【问题讨论】:

    标签: sql date oracle11g date-range


    【解决方案1】:

    您可以将分组依据用于最小值/最大值和关联的子查询以与table_b相关

    Select
        *
    From
        Table_b b
    Where
        Exists (
            Select
                'x'
            From
                table_a a
            Where
                a.id = b.id
            group by
                a.id
            having
                min(a.sdt) <= b.sdt and
                max(a.edt) >= b.sdt
      )
    

    Example Fiddle

    【讨论】:

      【解决方案2】:

      值得注意的是,在子查询中使用 GROUP BY 会产生不必要的性能成本。

      SELECT b.*
      FROM table_b b
      WHERE EXISTS (
          SELECT 1
          FROM table_a a
          WHERE b.sdt BETWEEN LEAST(a.sdt, e.edt) AND GREATEST(a.edt, a.sdt)
            AND a.id = b.id
      );
      

      编辑/更正:
      此解决方案仅适用于您匹配 table_a 中的各个行,而不是 MIN/MAX 分组。我之前忽略了 table_a 的 MIN/MAX 分组要求。

      以下使用两个没有 GROUP BY 的 EXISTS 查询并返回正确的结果:

      SELECT b.*
      FROM table_b b
      WHERE (EXISTS (
          SELECT 1
          FROM table_a a
          WHERE b.sdt >= a.sdt 
          AND a.id = b.id
      ) AND EXISTS (
          SELECT 1
          FROM table_a a
          WHERE b.sdt <= a.edt 
          AND a.id = b.id
      ));
      

      【讨论】:

      • 啊,我第一次读到这个时错过了分组要求。你是对的先生。 :) 如果它正在寻找针对单个行的 BETWEEN 匹配项,那么我的查询将是正确的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      相关资源
      最近更新 更多