Oracle 21c中的递归查询,以回顾过去3周

vdzxcuhz  于 2023-08-03  发布在  Oracle
关注(0)|答案(3)|浏览(92)

你能帮我在Oracle 21 c中创建一个递归查询或使用其他方法来解决这个问题吗?
我的数据有三列:Ride,Client和Date。weeknum列是我添加的。
我想要的是一个递归查询或类似的东西在过去3周回顾考虑到每个日期和检索客户端/S谁是目前在至少1骑在过去3周(每周没有例外)关于每个日期,他们和结果应该是像在列名为最终结果.
我把DDL和DML语句放在db fiddle https://dbfiddle.uk/RT1G3uSp中,包括我的尝试,但是我尝试过的都不起作用。首先,我试图把条件加入,然后我试图加入rn,但不是它应该的方式。
我想澄清我的要求-对于1号客户,我想知道他在过去3周内是否参加过任何骑行,如果他每周至少参加一次骑行,那么在第4周应该标记为1,在第5周,这就是为什么周数列也必须考虑在内,1号客户在第2周参加过骑行,3和4,他必须再次标记为1,有了之前的1,我们现在必须有2。在第6周,客户号1在第3周、第4周、第5周再次出现乘坐,并且他必须再次拥有1,该1加上之前的2应该拥有3。
这就是为什么我说递归查询,每次我们都要回去看看各自的客户端是否在过去的3周中至少有一次乘坐。这种方式应该适用于所有的客户端。
我希望它现在更有意义。
如果有什么不清楚的地方请再问我。
提前谢谢你的帮助

Ride    Client  Date           Weeknum  Final Result
1         1    1/2/2023           1               0
2         1    1/5/2023           1               0
3         3    1/6/2023           1               0
4         1    1/11/2023          2               0
5         2    1/12/2023          2               0
6         1    1/16/2023          3               0
7         2    1/19/2023          3               0
8         1    1/24/2023          4               1
9         2    1/24/2023          4               0
10        1    1/30/2023          5               2
11        2     2/2/2023          5               1
12        2     2/8/2023          6               2
13        1     2/9/2023          6               3

字符串

pu3pd22g

pu3pd22g1#

像这样的吗

CREATE TABLE PROB ( RIDE, CLIENT, DATA) AS
SELECT 1,1, DATE'2023-01-02' FROM DUAL UNION ALL 
SELECT 2,1, DATE'2023-01-05' FROM DUAL UNION ALL 
SELECT 3,3, DATE'2023-01-06' FROM DUAL UNION ALL 
SELECT 4,1, DATE'2023-01-11' FROM DUAL UNION ALL 
SELECT 5,2, DATE'2023-01-12' FROM DUAL UNION ALL 
SELECT 6,1, DATE'2023-01-16' FROM DUAL UNION ALL 
SELECT 7,2, DATE'2023-01-19' FROM DUAL UNION ALL 
SELECT 8,1, DATE'2023-01-24' FROM DUAL UNION ALL 
SELECT 9,2, DATE'2023-01-24' FROM DUAL UNION ALL 
SELECT 10,1, DATE'2023-01-30' FROM DUAL UNION ALL 
SELECT 11,2, DATE'2023-02-02' FROM DUAL 

select client,trunc(data,'IW') wk, count(*)
    from   prob
    group by client, trunc(data,'IW')
    order by 2,1;

字符串

enyaitl3

enyaitl32#

可以用MATCH_RECOGNIZE来解决:

WITH cte AS (
   -- single instance per client,week
   SELECT  CLIENT, MIN(RIDE) AS RIDE, trunc(data,'IW') AS date_week_trunc
   FROM PROB
   GROUP BY CLIENT, trunc(data,'IW')
)
SELECT 
  MR.*
  ,COUNT(MR.CLS) OVER(PARTITION BY CLIENT ORDER BY date_week_trunc) AS final_result
FROM cte  T
MATCH_RECOGNIZE (
   PARTITION BY CLIENT
   ORDER BY date_week_trunc
   MEASURES CLASSIFIER() AS CLS
   ALL ROWS PER MATCH WITH UNMATCHED ROWS
   PATTERN (B+)
   DEFINE B AS (    B.date_week_trunc = PREV(B.date_week_trunc,1) + 7
                AND B.date_week_trunc = PREV(B.date_week_trunc,2) + 14
                AND B.date_week_trunc = PREV(B.date_week_trunc,3) + 21
               )
) MR
ORDER BY RIDE;

字符串
输出量:
x1c 0d1x的数据

**db<>fiddle demo**第一个字符

工作原理:

  • 在每周开始时为每个客户端获取单个条目-date_week_trunc
  • 检查是否有前3周的每个条目-cls
  • 计算运行总数-final_result
yrdbyhpb

yrdbyhpb3#

我建议您使用外部apply来运行一个匹配所需条件的相关子查询,然后使用 case expressionrunning sum 的组合来应用最近添加到问题中的附加逻辑。

select
    t.*
  , xtra.prior_rides
  , sum(case when xtra.prior_rides > 0 then 1 end) 
      over(partition by client order by weeknum ASC) as wanted_value
from prob t
outer apply (
  select 
       count(*) as prior_rides 
  from prob p
  where t.CLIENT = p.CLIENT
  and t.data > p.data
  and p.data <= t.data - 21
  ) xtra
order by client, data DESC

字符串
| 客户服务|数据|周数|以前的游乐设施|WANTED_VALUE| WANTED_VALUE |
| --|--|--|--|--| ------------ |
| 一个|2023年2月9日|六个|四个|三个| 3 |
| 一个|23年1月30日|五个|二个|二个| 2 |
| 一个|23年1月24日|四个|一个|一个| 1 |
| 一个|23年1月16日|三个|0个| * 空 *| null |
| 一个|2023年1月11日|二个|0个| * 空 *| null |
| 一个|2023年1月5日|一个|0个| * 空 *| null |
| 一个|2023年1月2日|一个|0个| * 空 *| null |
| 二个|2023年2月8日|六个|一个|二个| 2 |
| 二个|2023年2月2日|五个|一个|一个| 1 |
| 二个|23年1月24日|四个|0个| * 空 *| null |
| 二个|23年1月19日|三个|0个| * 空 *| null |
| 二个|23年1月12日|二个|0个| * 空 *| null |
| 三个|2023年1月6日|一个|0个| * 空 *| null |
fiddle

nb以上结果中包含的额外数据:

INSERT INTO PROB
 SELECT 12, 2, DATE '2023-02-08', 6 FROM DUAL union all
 select 13, 1, DATE '2023-02-09', 6 FROM DUAL;


如果存在在前21天内没有发现游乐设施的“间隙”,则运行总和方法可能需要额外的逻辑。

相关问题