2016-01-24 2 views
1

У меня есть таблица, которая имеет две колонки АППАРАТА, 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   | 
+------+--------+----------------+ 

Извините, если я недостаточно ясен, дайте мне знать, если что-то вводит в заблуждение. Благодарю.

+0

Я удалил посторонние закладки базы данных. Добавьте соответствующий тег для используемой базы данных. –

ответ

3

Это должно производить то, что вы хотите:

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 

Если строки в вашей таблице различны id столбец не является необходимым.

+0

Благодарим за отзыв Husqvik, у вас отличное решение. Я отредактировал первый ряд H_TREE, как вы упомянули. – TheLastOne

1

Вы не должны этого делать. У вас должен быть столбец ParentID или что-то еще. Затем при необходимости создайте дерево.

Это пример (SQL Server), что провода все вместе:

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 
+0

Спасибо, JBrooks. – TheLastOne

0
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 и использовали таблицу, в которой было 500 строк, и она работала отлично. Спасибо всем за ваши ответы.

Смежные вопросы