创建将层次结构存储为逗号分隔值的列
Create column that stores hierarchy as comma separated values
我有一个 table,它有两列 UNIT,M_UNIT,如下所示:
+------+--------+
| UNIT | M_UNIT |
+------+--------+
| 10 | 12 |
| 15 | 19 |
| 12 | 16 |
| 13 | 15 |
| 19 | 14 |
| 14 | 11 |
+------+--------+
我想创建一个列 H_TREE,它在递归搜索 UNIT & M_UNIT 之后将层次结构存储为逗号分隔值,这样 H_TREE 以 UNIT 开始,以最后一个可能的 M_UNIT 结束,如下所示:
+------+--------+----------------+
| UNIT | M_UNIT | H_TREE |
+------+--------+----------------+
| 10 | 12 | 10,12,16 |
| 15 | 19 | 15,19,14,11 |
| 12 | 16 | 12,16 |
| 13 | 15 | 13,15,19,14,11 |
| 19 | 14 | 19,14,11 |
| 14 | 11 | 14,11 |
+------+--------+----------------+
抱歉,如果我不够清楚,如果有什么地方令人困惑,请告诉我。谢谢
这应该会产生您想要的结果:
WITH data (unit, m_unit) AS (
SELECT 10, 12 FROM dual UNION ALL
SELECT 15, 19 FROM dual UNION ALL
SELECT 12, 16 FROM dual UNION ALL
SELECT 13, 15 FROM dual UNION ALL
SELECT 19, 14 FROM dual UNION ALL
SELECT 14, 11 FROM dual)
SELECT
unit,
m_unit,
unit || ',' || listagg(root_unit, ',') WITHIN GROUP (ORDER BY depth) h_tree
FROM (
SELECT
id, unit, m_unit,
LEVEL depth, CONNECT_BY_ROOT m_unit root_unit
FROM
(SELECT ROWNUM id, unit, m_unit FROM data) data
CONNECT BY
PRIOR unit = m_unit)
GROUP BY
id,
unit,
m_unit
如果您的 table 中的行不同,则不需要 id
列。
你不应该这样做。您应该有一个名为 ParentID 或其他名称的列。然后在需要时构建树。
这是一个将它们连接在一起的示例(SQL 服务器):
USE AdventureWorks2008R2;
GO
WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level)
AS
(
-- Anchor member definition
SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
0 AS Level
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL
WHERE ManagerID IS NULL
UNION ALL
-- Recursive member definition
SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
Level + 1
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL
INNER JOIN DirectReports AS d
ON e.ManagerID = d.EmployeeID
)
-- Statement that executes the CTE
SELECT ManagerID, EmployeeID, Title, DeptID, Level
FROM DirectReports
INNER JOIN HumanResources.Department AS dp
ON DirectReports.DeptID = dp.DepartmentID
WHERE dp.GroupName = N'Sales and Marketing' OR Level = 0;
GO
WITH data (unit, m_unit) AS (
SELECT unit, m_unit from TABLE)
SELECT
unit,
m_unit,
unit || ',' || listagg(root_unit, ',') WITHIN GROUP (ORDER BY depth) h_tree
FROM (
SELECT
id, unit, m_unit,
LEVEL depth, CONNECT_BY_ROOT m_unit root_unit
FROM
(SELECT ROWNUM id, unit, m_unit FROM data) data
CONNECT BY
PRIOR unit = m_unit)
GROUP BY
id,
unit,
m_unit
我接受了 Husqvik 的回答,并使用了一个 table,它有 500 行并且运行良好。谢谢大家的回复。
我有一个 table,它有两列 UNIT,M_UNIT,如下所示:
+------+--------+ | UNIT | M_UNIT | +------+--------+ | 10 | 12 | | 15 | 19 | | 12 | 16 | | 13 | 15 | | 19 | 14 | | 14 | 11 | +------+--------+
我想创建一个列 H_TREE,它在递归搜索 UNIT & M_UNIT 之后将层次结构存储为逗号分隔值,这样 H_TREE 以 UNIT 开始,以最后一个可能的 M_UNIT 结束,如下所示:
+------+--------+----------------+ | UNIT | M_UNIT | H_TREE | +------+--------+----------------+ | 10 | 12 | 10,12,16 | | 15 | 19 | 15,19,14,11 | | 12 | 16 | 12,16 | | 13 | 15 | 13,15,19,14,11 | | 19 | 14 | 19,14,11 | | 14 | 11 | 14,11 | +------+--------+----------------+
抱歉,如果我不够清楚,如果有什么地方令人困惑,请告诉我。谢谢
这应该会产生您想要的结果:
WITH data (unit, m_unit) AS (
SELECT 10, 12 FROM dual UNION ALL
SELECT 15, 19 FROM dual UNION ALL
SELECT 12, 16 FROM dual UNION ALL
SELECT 13, 15 FROM dual UNION ALL
SELECT 19, 14 FROM dual UNION ALL
SELECT 14, 11 FROM dual)
SELECT
unit,
m_unit,
unit || ',' || listagg(root_unit, ',') WITHIN GROUP (ORDER BY depth) h_tree
FROM (
SELECT
id, unit, m_unit,
LEVEL depth, CONNECT_BY_ROOT m_unit root_unit
FROM
(SELECT ROWNUM id, unit, m_unit FROM data) data
CONNECT BY
PRIOR unit = m_unit)
GROUP BY
id,
unit,
m_unit
如果您的 table 中的行不同,则不需要 id
列。
你不应该这样做。您应该有一个名为 ParentID 或其他名称的列。然后在需要时构建树。
这是一个将它们连接在一起的示例(SQL 服务器):
USE AdventureWorks2008R2;
GO
WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level)
AS
(
-- Anchor member definition
SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
0 AS Level
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL
WHERE ManagerID IS NULL
UNION ALL
-- Recursive member definition
SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
Level + 1
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL
INNER JOIN DirectReports AS d
ON e.ManagerID = d.EmployeeID
)
-- Statement that executes the CTE
SELECT ManagerID, EmployeeID, Title, DeptID, Level
FROM DirectReports
INNER JOIN HumanResources.Department AS dp
ON DirectReports.DeptID = dp.DepartmentID
WHERE dp.GroupName = N'Sales and Marketing' OR Level = 0;
GO
WITH data (unit, m_unit) AS (
SELECT unit, m_unit from TABLE)
SELECT
unit,
m_unit,
unit || ',' || listagg(root_unit, ',') WITHIN GROUP (ORDER BY depth) h_tree
FROM (
SELECT
id, unit, m_unit,
LEVEL depth, CONNECT_BY_ROOT m_unit root_unit
FROM
(SELECT ROWNUM id, unit, m_unit FROM data) data
CONNECT BY
PRIOR unit = m_unit)
GROUP BY
id,
unit,
m_unit
我接受了 Husqvik 的回答,并使用了一个 table,它有 500 行并且运行良好。谢谢大家的回复。