创建将层次结构存储为逗号分隔值的列

Create column that stores hierarchy as comma separated values

我有一个 table,它有两列 UNITM_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 行并且运行良好。谢谢大家的回复。