英文:
How to create a recursive join in snowflake
问题
我有一个查询,其中包括多个左连接以获取员工的管理层次列表。我知道Snowflake有递归功能,但我在理解上有困难。有人知道如何递归地编写类似这样的查询吗?
select
d1.employee_id,
d1.employee_id1,
d1.employee_id2,
d1.employee_id3,
d2.employee_id1 as employee_id4,
d2.manager_name as employee_id4_name,
d3.employee_id1 as employee_id5,
d3.manager_name as employee_id5_name,
d4.employee_id1 as employee_id6,
d4.manager_name as employee_id6_name,
d5.employee_id1 as employee_id7,
d5.manager_name as employee_id7_name
from employees d1
left join employees d2
on d1.employee_id3 = d2.employee_id
and d1.report_effective_date = d2.report_effective_date
left join employees d3
on d2.employee_id1 = d3.employee_id
and d2.report_effective_date = d3.report_effective_date
left join employees d4
on d3.employee_id1 = d4.employee_id
and d3.report_effective_date = d4.report_effective_date
left join employees d5
on d4.employee_id1 = d5.employee_id
and d4.report_effective_date = d5.report_effective_date
根据我理解的方式,我尝试过以下内容,但似乎无法按我希望的格式排列?我想要获取个人的管理层次结构,但每个经理都在一个新列中。
with cte as (
select
employee_id,
employee_name,
employee_id1,
manager_name
from employees
where employee_name = <name>
union all
select
employee.employee_id,
employee.employee_name,
employee.employee_id1,
employee.manager_name
from employees
join cte
on employee.employee_id = cte.employee_id1
)
select * from cte
英文:
I have a query with a bunch of left joins to get a hierarchal list of managers for an employee. I know snowflake has a recursive functionality but having trouble following. Does anyone know how something like this can be written recursively?
select
d1.employee_id,
d1.employee_id1,
d1.employee_id2,
d1.employee_id3,
d2.employee_id1 as employee_id4,
d2.manager_name as employee_id4_name,
d3.employee_id1 as employee_id5,
d3.manager_name as employee_id5_name,
d4.employee_id1 as employee_id6,
d4.manager_name as employee_id6_name,
d5.employee_id1 as employee_id7,
d5.manager_name as employee_id7_name
from employees d1
left join employees d2
on d1.employee_id3 = d2.employee_id
and d1.report_effective_date = d2.report_effective_date
left join employees d3
on d2.employee_id1 = d3.employee_id
and d2.report_effective_date = d3.report_effective_date
left join employees d4
on d3.employee_id1 = d4.employee_id
and d3.report_effective_date = d4.report_effective_date
left join employees d5
on d4.employee_id1 = d5.employee_id
and d4.report_effective_date = d5.report_effective_date
Edit with what I've tried - and from my understanding the way I want this formatted doesn't seem possible? I'm looking to get an individual's manager hierarchy but with each manager in a new column.
What I tried was like this, but it would give me the hierarchy in rows and would require that I have an anchored query filtered to someone.
with cte as (
select
employee_id,
employee_name,
employee_id1,
manager_name
from employees
where employee_name = <name>
union all
select
employee.employee_id,
employee.employee_name,
employee.employee_id1,
employee.manager_name
from employees
join cte
on employee.employee_id = cte.employee_id1
)
select * from cte
答案1
得分: 1
你说得对,你会得到行而不是列。你还说得对,你需要在查询中锚定某个人或某个群体。考虑将一个没有分配employee_id1的员工作为锚点(如果我理解你的数据的话,这个员工是组织中的最高层)。
至于"Data in rows",考虑构建一个层次路径,你可以将其拆分成数组或其他形式:
with cte as (
select
employee_id as employee,
employee_name,
employee_id1 as manager,
manager_name,
CAST(employee_id AS VARCHAR(500)) as path,
1 as depth
from employees
where employee_id1 IS NULL
union all
select
employee.employee_id,
employee.employee_name,
employee.employee_id1,
employee.manager_name,
cte.path || '>' || employee.employee_id,
cte.depth + 1
from employees
join cte
on employee.employee_id = cte.employee_id1
)
select * from cte
现在你有了员工的完整路径以及该员工的深度,这应该会有很大帮助。
英文:
You are correct that you would get back rows instead of columns. You are also correct that you would need to anchor the query on someone, or some group. Consider, as an anchor, an employee that has no employee_id1 assigned (The top most person in the org, if I understand your data).
As for the "Data in rows" consider building a hierarchical path that you can split to an array or what-have-you:
with cte as (
select
employee_id as employee,
employee_name,
employee_id1 as manager,
manager_name,
CAST(employee_id AS VARCHAR(500)) as path,
1 as depth
from employees
where employee_id1 IS NULL
union all
select
employee.employee_id,
employee.employee_name,
employee.employee_id1,
employee.manager_name,
cte.path || '>' || employee.employee_id,
cte.depth + 1
from employees
join cte
on employee.employee_id = cte.employee_id1
)
select * from cte
Now you have the full path for the employee as well as the depth of that employee, which should help plenty.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论