如何使用 BigQuery 显示自连接树层次结构 table?
How to display self-joined tree hierarchy table by using BigQuery?
我正在处理主管及其下属员工的树状层次结构。难的是有些主管是其他主管下属的员工,而且数量很多。
对于我从class获得的SQL查询,只有简单的自连接,可能只有两个级别:A被B监督,仅此而已。
但现实世界的问题要复杂得多。有多个级别,我不确定确切的数量。比如A被B监管,B被C监管,C被D监管等等
我假设只有 4 个级别的监督。
原始数据可能是这样的:
Employee Supervisor
A B
C B
D B
B V
E V
F E
G V
V (Blank which indicates no boss)
因此我生成了如下代码:
SELECT T1.Supervisor,ifnull(T2.EmployeeName, 'No Boss') as sup_emp1,
ifnull(T3.EmployeeName, 'No Boss') as sup_emp2, ifnull(T4.EmployeeName,
'No boss') as sup_emp3, ifnull(T5.EmployeeName, 'No Boss') as EMPLOYEE
FROM T1
LEFT JOIN T2
ON T1.Supervisor=T2.EmployeeName
LEFT JOIN T3
ON T2.Supervisor = T3.EmployeeName
LEFT JOIN T4
ON T3.Supervisor = T4.EmployeeName
LEFT JOIN T5
ON T4.Supervisor = T5.EmployeeName
WHERE T5. Emp_Status = 'Active'
ORDER BY T1.Supervisor ASC
然而,结果却是错误的。我只是对 table 的关系感到困惑,没有想到递归连接。
预期的结果应该是这样的:
Supervisor # of Employees
V 7(include indirect supervised employees)
B 3
E 1
组织 table 应该是:
Supervisor Employee1 Employee2
V B A
V B C
V B D
V E F
V G Null
但是我的结果竟然是
Supervisor Employee1 Employee2
V B A
V B C
V B D
V E F
V V G
<- 我需要 G 在第二层。
那么,有人可以帮忙吗?谢谢!
我想你想要:
SELECT T1.Supervisor as BigBoss,
T2.EmployeeName as level1,
T3.EmployeeName as level2,
T4.EmployeeName as level3,
T5.EmployeeName as level4
FROM T T1 LEFT JOIN
T T2
ON T1.Supervisor=T2.EmployeeName AND T2.Emp_Status = 'Active' LEFT JOIN
T T3
ON T2.Supervisor = T3.EmployeeName AND T3.Emp_Status = 'Active' LEFT JOIN
T T4
ON T3.Supervisor = T4.EmployeeName AND T4.Emp_Status = 'Active' LEFT JOIN
T T5
ON T4.Supervisor = T5.EmployeeName AND T5.Emp_Status = 'Active'
WHERE T1.Emp_Status = 'Active' AND
NOT EXISTS (SELECT 1
FROM T ts
WHERE ts.EmployeeName = T1.SuperVisor
)
ORDER BY 1, 2, 3, 4, 5 ASC;
这从大老板开始,然后逐步下降。
... assume there are only like 4 levels for supervision ...
以下适用于 BigQuery 标准 SQL 并且只需将更多 LEFT JOIN 和相应字段添加到 COALESCE
即可轻松扩展到更多(合理更多)级别
#standardSQL
SELECT t.Supervisor,
IF(t.Supervisor = t5.Supervisor,
STRUCT(Employee2 AS Employee1, NULL AS Employee2),
STRUCT(t5.Supervisor AS Employee1, Employee2 AS Employee2)
).*
FROM (
SELECT t1.Employee Supervisor,
COALESCE(t4.Employee, t3.Employee, t2.Employee) Employee2
FROM `project.dataset.table` t1
LEFT JOIN `project.dataset.table` t2 ON t2.Supervisor = t1.Employee
LEFT JOIN `project.dataset.table` t3 ON t3.Supervisor = t2.Employee
LEFT JOIN `project.dataset.table` t4 ON t4.Supervisor = t3.Employee
WHERE t1.Supervisor IS NULL
) t
LEFT JOIN `project.dataset.table` t5 ON t5.Employee = t.Employee2
如果应用于您问题中的示例数据 - 结果是
Row Supervisor Employee1 Employee2
1 V B A
2 V B C
3 V B D
4 V E F
5 V G null
我正在处理主管及其下属员工的树状层次结构。难的是有些主管是其他主管下属的员工,而且数量很多。
对于我从class获得的SQL查询,只有简单的自连接,可能只有两个级别:A被B监督,仅此而已。
但现实世界的问题要复杂得多。有多个级别,我不确定确切的数量。比如A被B监管,B被C监管,C被D监管等等
我假设只有 4 个级别的监督。 原始数据可能是这样的:
Employee Supervisor
A B
C B
D B
B V
E V
F E
G V
V (Blank which indicates no boss)
因此我生成了如下代码:
SELECT T1.Supervisor,ifnull(T2.EmployeeName, 'No Boss') as sup_emp1,
ifnull(T3.EmployeeName, 'No Boss') as sup_emp2, ifnull(T4.EmployeeName,
'No boss') as sup_emp3, ifnull(T5.EmployeeName, 'No Boss') as EMPLOYEE
FROM T1
LEFT JOIN T2
ON T1.Supervisor=T2.EmployeeName
LEFT JOIN T3
ON T2.Supervisor = T3.EmployeeName
LEFT JOIN T4
ON T3.Supervisor = T4.EmployeeName
LEFT JOIN T5
ON T4.Supervisor = T5.EmployeeName
WHERE T5. Emp_Status = 'Active'
ORDER BY T1.Supervisor ASC
然而,结果却是错误的。我只是对 table 的关系感到困惑,没有想到递归连接。
预期的结果应该是这样的:
Supervisor # of Employees
V 7(include indirect supervised employees)
B 3
E 1
组织 table 应该是:
Supervisor Employee1 Employee2
V B A
V B C
V B D
V E F
V G Null
但是我的结果竟然是
Supervisor Employee1 Employee2
V B A
V B C
V B D
V E F
V V G
<- 我需要 G 在第二层。
那么,有人可以帮忙吗?谢谢!
我想你想要:
SELECT T1.Supervisor as BigBoss,
T2.EmployeeName as level1,
T3.EmployeeName as level2,
T4.EmployeeName as level3,
T5.EmployeeName as level4
FROM T T1 LEFT JOIN
T T2
ON T1.Supervisor=T2.EmployeeName AND T2.Emp_Status = 'Active' LEFT JOIN
T T3
ON T2.Supervisor = T3.EmployeeName AND T3.Emp_Status = 'Active' LEFT JOIN
T T4
ON T3.Supervisor = T4.EmployeeName AND T4.Emp_Status = 'Active' LEFT JOIN
T T5
ON T4.Supervisor = T5.EmployeeName AND T5.Emp_Status = 'Active'
WHERE T1.Emp_Status = 'Active' AND
NOT EXISTS (SELECT 1
FROM T ts
WHERE ts.EmployeeName = T1.SuperVisor
)
ORDER BY 1, 2, 3, 4, 5 ASC;
这从大老板开始,然后逐步下降。
... assume there are only like 4 levels for supervision ...
以下适用于 BigQuery 标准 SQL 并且只需将更多 LEFT JOIN 和相应字段添加到 COALESCE
即可轻松扩展到更多(合理更多)级别#standardSQL
SELECT t.Supervisor,
IF(t.Supervisor = t5.Supervisor,
STRUCT(Employee2 AS Employee1, NULL AS Employee2),
STRUCT(t5.Supervisor AS Employee1, Employee2 AS Employee2)
).*
FROM (
SELECT t1.Employee Supervisor,
COALESCE(t4.Employee, t3.Employee, t2.Employee) Employee2
FROM `project.dataset.table` t1
LEFT JOIN `project.dataset.table` t2 ON t2.Supervisor = t1.Employee
LEFT JOIN `project.dataset.table` t3 ON t3.Supervisor = t2.Employee
LEFT JOIN `project.dataset.table` t4 ON t4.Supervisor = t3.Employee
WHERE t1.Supervisor IS NULL
) t
LEFT JOIN `project.dataset.table` t5 ON t5.Employee = t.Employee2
如果应用于您问题中的示例数据 - 结果是
Row Supervisor Employee1 Employee2
1 V B A
2 V B C
3 V B D
4 V E F
5 V G null