如何在Oracle中执行递归搜索

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

我目前在理解 Oracle SQL 中递归搜索的实现方面遇到了挑战。

我遇到的 HackerRank 问题需要应用这个概念。虽然我没有透露具体的 HackerRank 查询,但我打算利用它作为参考来独立设计逻辑。然而,我寻求帮助来剖析这个问题并理解其复杂性。

如果有人拥有替代方法来实现预期结果,我愿意探索不同的解决方案。您的贡献和见解受到高度重视,我热切期待您的回应。

以下是我的场景。

我有一张桌子叫:

employee

它作为

3
列 ->
emp_id , emp_date , emp_task

数据如下

EMP_ID | EMP_DATE   | EMP_TASK
A1     | 01-04-2024 | 345
A2     | 01-04-2024 | 546
A3     | 01-04-2024 | 232
A4     | 01-04-2024 | 8000
A5     | 01-04-2024 | 2344
A1     | 02-04-2024 | 456
A2     | 02-04-2024 | 9280
A3     | 02-04-2024 | 324
A2     | 02-04-2024 | 754
A8     | 02-04-2024 | 75 
A2     | 03-04-2024 | 400
A3     | 03-04-2024 | 234
A3     | 04-04-2024 | 100

条件是计算参与的

total number of emp_id

里面明确提到:统计每天参与的emp_id。

确保它们从一开始就是他们的。

这是我需要递归实现的逻辑,但不知道如何开始编写查询?。

如果您看到第 1 天:

01-04-2024
-> emp_id 参与 ->
A1 , A2 , A3 , A4 , A5

如果您看到第 2 天:

02-04-2024    -> emp_id participated -> 
A1、A2、A3`。他们也是参加第一天的人,所以参与的 emp_id 数量为 3

同样如此,直到结束。

注意: 第一天参加的人需要考虑到最后。他们正在参加。

A8
在中间加入,因为这
emp_id
不是第一天的一部分,所以在计数中不考虑它。

所以我的预期输出低于需要实现的

emp_date   cout_participated 
01-04-2024 5  
02-04-2024 3
03-04-2024 2
04-04-2024 1

我的试验未完全实施

WITH get_initial_day_emp_participated AS ( 
   -- Fetching all emp_id who initially participated
    SELECT
        *
    FROM
        employee
    WHERE
        emp_date = (
            SELECT
                MIN(emp_date)
            FROM
                employee
        )
), get_count_initial_day_participated AS ( 
  -- Using group getting the count of emp_id who initially participated 
    SELECT
        emp_date,
        COUNT(DISTINCT emp_id)
    FROM
        get_initial_day_emp_participated
    GROUP BY
        emp_date
), get_details_except_first_date AS (
   -- Fetching all details except first day participated
    SELECT
        *
    FROM
        employee
    WHERE
        emp_date != (
            SELECT
                MIN(emp_date)
            FROM
                employee
        )
)
SELECT
    *
FROM
    get_details_except_first_date;

为您提供创建表格和插入详细信息的参考

create table employee
(
   EMP_ID     varchar2(10),
   EMP_DATE   date,
   EMP_TASK   number
);

Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A1',to_date('01-04-2024','DD-MM-YYYY'),345);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A2',to_date('01-04-2024','DD-MM-YYYY'),546);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A3',to_date('01-04-2024','DD-MM-YYYY'),232);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A4',to_date('01-04-2024','DD-MM-YYYY'),8000);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A5',to_date('01-04-2024','DD-MM-YYYY'),2344);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A1',to_date('02-04-2024','DD-MM-YYYY'),456);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A2',to_date('02-04-2024','DD-MM-YYYY'),9280);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A3',to_date('02-04-2024','DD-MM-YYYY'),324);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A2',to_date('02-04-2024','DD-MM-YYYY'),754);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A8',to_date('02-04-2024','DD-MM-YYYY'),75);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A2',to_date('03-04-2024','DD-MM-YYYY'),400);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A3',to_date('03-04-2024','DD-MM-YYYY'),234);
Insert into employee (EMP_ID,EMP_DATE,EMP_TASK) values ('A3',to_date('04-04-2024','DD-MM-YYYY'),100);
sql oracle recursion
1个回答
0
投票

这不是递归的,但另一种方法是计算已经过去的天数以及 emp_id 处于活动状态的天数:

select emp_id, emp_date,
  emp_date - min(emp_date) over() + 1 as day_num,
  count(*) over (partition by emp_id order by emp_date) emp_day_num
from (
  select distinct emp_id, emp_date
  from employee
)
order by emp_date, emp_id
EMP_ID EMP_DATE DAY_NUM EMP_DAY_NUM
A1 24 年 4 月 1 日 1 1
A2 24 年 4 月 1 日 1 1
A3 24 年 4 月 1 日 1 1
A4 24 年 4 月 1 日 1 1
A5 24 年 4 月 1 日 1 1
A1 24 年 4 月 2 日 2 2
A2 24 年 4 月 2 日 2 2
A3 24 年 4 月 2 日 2 2
A8 24 年 4 月 2 日 2 1
A2 24 年 4 月 3 日 3 3
A3 24 年 4 月 3 日 3 3
A3 24 年 4 月 4 日 4 4

子查询是因为

count(distinct emp_id) over ...
不被允许。

然后查看它们是否匹配,并计算匹配的:

select emp_date, count(emp_id)
from (
  select emp_id, emp_date,
    emp_date - min(emp_date) over() + 1 as day_num,
    count(*) over (partition by emp_id order by emp_date) emp_day_num
  from (
    select distinct emp_id, emp_date
    from employee
  )
)
where emp_day_num = day_num
group by emp_date
order by emp_date
EMP_DATE COUNT(EMP_ID)
24 年 4 月 1 日 5
24 年 4 月 2 日 3
24 年 4 月 3 日 2
24 年 4 月 4 日 1

小提琴

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