Sql 如何使用递归查询获得平均值
我正在尝试使用postgres编写递归查询,其工作正常,并返回用户5下的所有用户,代码如下:Sql 如何使用递归查询获得平均值,sql,postgresql,Sql,Postgresql,我正在尝试使用postgres编写递归查询,其工作正常,并返回用户5下的所有用户,代码如下: WITH RECURSIVE subordinates AS ( SELECT id, supervisor_id, name FROM employees WHERE id = 5 UNION SELECT e.id, e.supervisor_id,
WITH RECURSIVE subordinates AS (
SELECT
id,
supervisor_id,
name
FROM
employees
WHERE
id = 5
UNION
SELECT
e.id,
e.supervisor_id,
e.name
FROM
employees e
INNER JOIN subordinates s ON s.id = e.supervisor_id
) SELECT
*
FROM
subordinates;
但我还有一张叫做饼干的桌子,它有三列:类型、重量和烹调方式
现在,我需要id、姓名和主管id的饼干的平均重量,但有一个小小的转折点,如果用户id 1在3以下,3在4以下,4在5以下,那么它应该返回所有1、3、4和5由员工id记录烹调的饼干的平均重量,并且一个用户可以在饼干中有多个记录
我试过了,但没用
WITH RECURSIVE subordinates AS (
SELECT
e.id,
e.supervisor_id,
e.name,
AVG(b.weight)
FROM
employees e
LEFT JOIN burrito b ON
e.id=b.cooked_by_employee_id
WHERE
e.id = 5
UNION
SELECT
e.id,
e.supervisor_id,
e.name,
b.weight
FROM
employees e
INNER JOIN subordinates s ON s.id = e.supervisor_id
LEFT JOIN burrito b ON b.cooked_by_employee_id=e.supervisor_id
) SELECT
*
FROM
subordinates;
样本数据:
员工
:
+----+------+---------------+
| id | name | supervisor_id |
+----+------+---------------+
| 1 | a | 3 |
+----+------+---------------+
| 2 | b | 4 |
+----+------+---------------+
| 3 | c | 5 |
+----+------+---------------+
| 4 | d | 0 |
+----+------+---------------+
| 5 | e | 0 |
+----+------+---------------+
+----+-------+--------+-----------------------+
| id | type | weight | cooked_by_employee_id |
+----+-------+--------+-----------------------+
| 1 | sweet | 1 | 1 |
+----+-------+--------+-----------------------+
| 2 | salty | 2 | 1 |
+----+-------+--------+-----------------------+
| 3 | sweet | 3 | 3 |
+----+-------+--------+-----------------------+
玉米煎饼
:
+----+------+---------------+
| id | name | supervisor_id |
+----+------+---------------+
| 1 | a | 3 |
+----+------+---------------+
| 2 | b | 4 |
+----+------+---------------+
| 3 | c | 5 |
+----+------+---------------+
| 4 | d | 0 |
+----+------+---------------+
| 5 | e | 0 |
+----+------+---------------+
+----+-------+--------+-----------------------+
| id | type | weight | cooked_by_employee_id |
+----+-------+--------+-----------------------+
| 1 | sweet | 1 | 1 |
+----+-------+--------+-----------------------+
| 2 | salty | 2 | 1 |
+----+-------+--------+-----------------------+
| 3 | sweet | 3 | 3 |
+----+-------+--------+-----------------------+
因此,如果它为employee_id5
运行,那么它应该返回
+-------------+------+-----------------------------------------------------+
| employee_id | name | weight |
+-------------+------+-----------------------------------------------------+
| 5 | e | 2 (Average 2 because both 1 and 3 id comes under 5) |
+-------------+------+-----------------------------------------------------+
你已经计算出了递归CTE,这可能是战斗的一半(或更多)。但是,以下内容构建了一个稍有不同的版本。递归cte(path_to_chef)获取员工ID并构建从顶层到员工的路径。然后,第二个cte(cook_chef)将路径字符串剥离回顶级员工id。结果包含两列,员工id和根级别员工的员工id。然后,这将设置阶段以与其他表连接以获得最终结果
通过在指定的位置提供id,该查询可以作为独立查询,也可以用于单个根级别。但我倾向于创建通用的可重用例程,所以我将其包装到了一个SQL函数中
create or replace function chef_avg_burrito_weight()
returns table ( employee_id integer
, name text
, weight numeric
)
language sql
as $$
with recursive path_to_chef as
( select id, trim(to_char(id, '9999'))||'>' path
from employees
where supervisor_id = 0
union all
select e.id, path || trim(to_char(e.id, '9999'))||'>'
from employees e
join path_to_chef c on e.supervisor_id = c.id
) -- select * from path_to_chef
, cook_chef as
(select id cook
, substring(path from '^([[:digit:]]+)>')::integer chef
from path_to_chef
) -- select * from cook_chef
select e.id, e.name, round(avg(b.weight),2) average_weight
from burrito b
join cook_chef c on (b.cooked_by_employee_id = c.cook)
join employees e on (e.id = c.chef)
-- where chef = 5
group by e.id, e.name;
$$;
-- test
select *
from chef_avg_burrito_weight()
where employee_id = 5;
“样本数据和期望的结果将非常有用。@GordonLinoff添加了样本数据和期望的结果