【问题标题】:Oracle SQL - compare date with range of datesOracle SQL - 将日期与日期范围进行比较
【发布时间】:2017-12-31 21:47:42
【问题描述】:

我在按 product_id 比较分区中的一个日期时遇到问题。我需要检查 date_to desc 排序的最后一个 date_to 是否在 date_from 和 date_to 之间。

下面是分区示例:

product_id | date_from | date_to

 1     | 2017-01-01| 2019-05-01
 1     | 2017-04-15| 2017-06-10
 1     | 2017-03-15| 2017-03-25
 1     | 2017-01-19| 2017-02-01

如何检查最后一行中的日期是否在 product_id 分区中的任何日期范围之间。这个订单必须是完整的。我尝试使用 LAG 函数,但它只会检查以前的范围,我尝试使用 min(date_from) 和 max(date_to) 即使在这里也会有问题,因为 min 来自第一行,max 来自第二行,并且资格是错误的,因为我需要按产品检查每个日期范围,而不是整个范围。解决方案将检查:

*2017-02-01(分区的第一行)2017-01-01 和 2019-05-01(真)

*2017-02-01(分区的第二行)2017-04-15 和 2017-06-10(FALSE)之间

*2017-02-01 (第三行分区) 2017-03-15 和 2017-03-25 (FALSE) 之间

结果:是的!日期在某个日期范围之间;)好的,只需标志 1 就足够了 :)

如果您能提供任何帮助,我将不胜感激,对我的英语感到抱歉:)

编辑: 当前的问题是如何按照以前的范围检查每个 date_to。例如

(第二个 date_to) 2017-06-10 之间 (第一行) 2017-01-01| 2019-05-01

(第三个date_to) 2017-03-25 之间(第一行) 2017-01-01| 2019-05-01 和(第三个 date_to)2017-03-25 之间(第二行)2017-04-15| 2017-06-10

等等

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    试试:

    SELECT t1.*,
           CASE WHEN first_value( date_to ) OVER (Partition by product_id Order by date_to )
                     BETWEEN date_from AND date_to
                     THEN 'Y' ELSE 'N'
           END As my_flag
    FROM table1 t1
    ORDER BY date_to DESC
    

    演示:http://sqlfiddle.com/#!4/b351f/4

    | PRODUCT_ID |             DATE_FROM |               DATE_TO | MY_FLAG |
    |------------|-----------------------|-----------------------|---------|
    |          1 | 2017-01-01 00:00:00.0 | 2019-05-01 00:00:00.0 |       Y |
    |          1 | 2017-04-15 00:00:00.0 | 2017-06-10 00:00:00.0 |       N |
    |          1 | 2017-03-15 00:00:00.0 | 2017-03-25 00:00:00.0 |       N |
    |          1 | 2017-01-19 00:00:00.0 | 2017-02-01 00:00:00.0 |       Y |
    

    【讨论】:

    • 看起来相当不错!我会试试看。你知道如何用以前的范围检查每个 date_to 吗?例如,第二行的日期与第一行比较,第三行与第一行和第二行比较,最后一行与第一行、第二行和第三行比较...
    【解决方案2】:

    试试这个:

    WITH results AS (
      SELECT
        t.product_id,
        max(case when t.min_date_to BETWEEN t.date_from AND t.date_to
          then 1
          else 0
        end) AS result
      FROM (
        SELECT
          x.*,
          min(x.date_to) over (partition by x.product_id) AS min_date_to
        FROM
          your_table x
      ) t
    )
    SELECT DISTINCT
      x.product_id,
      r.result
    FROM
      your_table x
    JOIN
      results r ON r.product_id = x.product_id;
    

    结果如下:

    | PRODUCT_ID | RESULT  |
    |------------|---------|
    |        111 |       1 |
    |        222 |       1 |
    |        333 |       0 |
    |        444 |       1 |
    |        554 |       0 |
    

    此查询检查每个产品的最小date_to,该产品具有该特定产品的先前日期范围。因此,对于那些具有至少 date_to 与该产品的至少一个日期范围匹配的产品,您会得到“1”,或者“0” - 在其他情况下。

    【讨论】:

    • 请看我对下一篇文章的评论。
    • 对查询添加了微小的更改:“结果”CTE 的最大函数。请看一看。
    • Vadym 感谢您的消息,但这仍然只比较 min_date_to,现在我需要检查每个日期与之前的范围 date_from 和 date_to。正确的程序将比较 date_to 中的第二个日期并将其与之前的范围进行比较。接下来从 date_to 获取第三个日期,并与第一行的范围进行比较,并与第二个范围进行比较......我在我的问题中添加了编辑。
    猜你喜欢
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多