使用窗口函数的递归查询

问题描述 投票:0回答:1

所以,我有一张桌子:

   DATE     STORE   PRODUCT
01.01.2020  Store1  Product1
01.01.2020  Store1  Product2
01.01.2020  Store1  Product3
01.01.2020  Store1  Product4
01.02.2020  Store1  Product5
01.02.2020  Store1  Product6
01.02.2020  Store1  Product7
01.02.2020  Store1  Product8
01.01.2020  Store2  Product1
01.01.2020  Store2  Product2
01.01.2020  Store2  Product3
01.01.2020  Store2  Product4
03.01.2020  Store2  Product1
01.03.2020  Store2  Product2
02.03.2020  Store2  Product8
03.03.2020  Store2  Product10
06.08.2020  Store2  Product6
08.11.2020  Store2  Product7

我需要计算不同的商店。 而且,如果之前的行之间相隔超过 20 天,则 store 的值是唯一的

我的期望:

   date Store   Product Product_x
01.01.2020  Store1  Product1    1
01.01.2020  Store1  Product2    1
01.01.2020  Store1  Product3    1
01.01.2020  Store1  Product4    1
01.02.2020  Store1  Product5    1e
01.02.2020  Store1  Product6    1e
01.02.2020  Store1  Product7    1e
01.02.2020  Store1  Product8    1e
01.01.2020  Store2  Product1    2
01.01.2020  Store2  Product2    2
01.01.2020  Store2  Product3    2
01.01.2020  Store2  Product4    2
03.01.2020  Store2  Product1    2
01.03.2020  Store2  Product2    2e
02.03.2020  Store2  Product8    2e
03.03.2020  Store2  Product10   2e
06.08.2020  Store2  Product6    2ee
08.11.2020  Store2  Product7    2eee

我所拥有的和我的疑问:

    DATE_   STORE   PRODUCT TT
01.01.2020  Store1  Product1    1
01.01.2020  Store1  Product2    1
01.01.2020  Store1  Product3    1
01.01.2020  Store1  Product4    1
01.02.2020  Store1  Product8    1e
01.02.2020  Store1  Product7    1
01.02.2020  Store1  Product5    1
01.02.2020  Store1  Product6    1
01.01.2020  Store2  Product4    2
01.01.2020  Store2  Product3    2
01.01.2020  Store2  Product2    2
01.01.2020  Store2  Product1    2
03.01.2020  Store2  Product1    2
01.03.2020  Store2  Product2    2e
02.03.2020  Store2  Product8    2
03.03.2020  Store2  Product10   2
06.08.2020  Store2  Product6    2e
08.11.2020  Store2  Product7    2e

查询:

 select p.*, case
                  when p.date_ - lag(p.date_, 1) over ( partition by p.store order by p.date_)>20
                  then to_char(dense_rank() over (order by p.store)) || 'e'
                  else to_char(dense_rank() over (order by p.store)) end tt 
from table p;

如何解决这个问题? 如果日期之间的差异超过 20 天,如何应用递归函数添加“e”?

sql oracle recursive-query
1个回答
0
投票

从 Oracle 12 开始,您可以使用

MATCH_RECOGNIZE
进行逐行模式匹配:

SELECT dt,
       store,
       product,
       DENSE_RANK() OVER (ORDER BY store) || LPAD('e', mn - 1, 'e') AS tt
FROM   table_name
       MATCH_RECOGNIZE(
         PARTITION BY store
         ORDER BY dt, product
         MEASURES
           MATCH_NUMBER() AS mn
         ALL ROWS PER MATCH
         PATTERN (first_row within_20_day* )
         DEFINE
           within_20_day AS dt <= FIRST(dt) + INTERVAL '20' DAY
       )

对于样本数据:

CREATE TABLE table_name (dt, STORE, PRODUCT) AS
SELECT DATE '2020-01-01', 'Store1', 'Product1' FROM DUAL UNION ALL
SELECT DATE '2020-01-01', 'Store1', 'Product2' FROM DUAL UNION ALL
SELECT DATE '2020-01-01', 'Store1', 'Product3' FROM DUAL UNION ALL
SELECT DATE '2020-01-01', 'Store1', 'Product4' FROM DUAL UNION ALL
SELECT DATE '2020-02-01', 'Store1', 'Product5' FROM DUAL UNION ALL
SELECT DATE '2020-02-01', 'Store1', 'Product6' FROM DUAL UNION ALL
SELECT DATE '2020-02-01', 'Store1', 'Product7' FROM DUAL UNION ALL
SELECT DATE '2020-02-01', 'Store1', 'Product8' FROM DUAL UNION ALL
SELECT DATE '2020-01-01', 'Store2', 'Product1' FROM DUAL UNION ALL
SELECT DATE '2020-01-01', 'Store2', 'Product2' FROM DUAL UNION ALL
SELECT DATE '2020-01-01', 'Store2', 'Product3' FROM DUAL UNION ALL
SELECT DATE '2020-01-01', 'Store2', 'Product4' FROM DUAL UNION ALL
SELECT DATE '2020-01-03', 'Store2', 'Product1' FROM DUAL UNION ALL
SELECT DATE '2020-03-01', 'Store2', 'Product2' FROM DUAL UNION ALL
SELECT DATE '2020-03-02', 'Store2', 'Product8' FROM DUAL UNION ALL
SELECT DATE '2020-03-03', 'Store2', 'Product10' FROM DUAL UNION ALL
SELECT DATE '2020-08-06', 'Store2', 'Product6' FROM DUAL UNION ALL
SELECT DATE '2020-11-08', 'Store2', 'Product7' FROM DUAL;

输出:

DT 商店 产品 TT
2020-01-01 00:00:00 商店1 产品1 1
2020-01-01 00:00:00 商店1 产品2 1
2020-01-01 00:00:00 商店1 产品3 1
2020-01-01 00:00:00 商店1 产品4 1
2020-02-01 00:00:00 商店1 产品5 1e
2020-02-01 00:00:00 商店1 产品6 1e
2020-02-01 00:00:00 商店1 产品7 1e
2020-02-01 00:00:00 商店1 产品8 1e
2020-01-01 00:00:00 商店2 产品1 2
2020-01-01 00:00:00 商店2 产品2 2
2020-01-01 00:00:00 商店2 产品3 2
2020-01-01 00:00:00 商店2 产品4 2
2020-01-03 00:00:00 商店2 产品1 2
2020-03-01 00:00:00 商店2 产品2 2e
2020-03-02 00:00:00 商店2 产品8 2e
2020-03-03 00:00:00 商店2 产品10 2e
2020-08-06 00:00:00 商店2 产品6 2ee
2020-11-08 00:00:00 商店2 产品7 2ee

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.