Я немного боролся с созданием структуры уровня иерархии учетных записей с помощью SQL и надеюсь, что кто-то может мне помочь.
Я могу получить уровни, если передам одну запись «самого высокого уровня» в запрос и выведуобратно уровни иерархии, но мне нужно объединить это для всех записей, чтобы вернуть полный набор результатов.
Я покажу свои примеры ниже.
Структуры таблиц ниже:
Основная таблица с самым высоким уровнем и идентификатором
ID Code
---------------
2341 ACC0070
5689 ACC0590
Таблица суровни иерархии
Code Indention Name
---------------------------------
ACC0010 0 Level 1
ACC0015 1 Level 2
ACC0030 2 Level 3
ACC0065 2 Level 3
ACC0070 3 Level 4
ACC0155 0 Level 1
ACC0460 1 Level 2
ACC0500 2 Level 3
ACC0585 2 Level 3
ACC0587 3 Level 4
ACC0590 3 Level 4
Конечный результат должен быть следующим:
ID Code Indentation Name
----------------------------------------
2341 ACC0010 0 Level 1
2341 ACC0015 1 Level 2
2341 ACC0065 2 Level 3
2341 ACC0070 3 Level 4
5689 ACC0155 0 Level 1
5689 ACC0460 1 Level 2
5689 ACC0585 2 Level 3
5689 ACC0590 3 Level 4
В отступе будет только 4 уровня.
Уровни иерархии, которые должны быть возвращены, будутвсегда быть MAX([Code])
для предыдущего отступа для любого [Code]
, меньшего, чем наивысшая запись отступа.
Пример кода, который у меня есть, если я передам [Code]
записи с отступом уровня 3. Это вернет правильные результаты для одной записи
SELECT
MAX(RowNr) AS [RowNr], MAX([Code]), Indentation
FROM
(SELECT
ROW_NUMBER() OVER (PARTITION BY Indentation ORDER BY [Code], Indentation DESC) AS [RowNr],
[Code], Indentation, [Name]
FROM
<tablename>
WHERE
[Code] <= 'ACC0070') AS res
GROUP BY
Indentation
Таким образом, в основном запрос должен выполняться для каждой записи со значением отступа 3 и возвращать уровни для всех записей.
Заранее спасибо.
РЕДАКТИРОВАТЬ
Я могу получить желаемые результаты с помощью курсора. Не уверен, что это будет возможно без использования курсора. Это было бы идеально.
-- Cursor Example
IF OBJECT_ID('tempdb..#HierarchyGL') IS NOT NULL DROP TABLE #HierarchyGL
GO
CREATE TABLE #HierarchyGL
(
No_ VARCHAR(50),
[Code] VARCHAR(50),
[Name] VARCHAR(50)
);
IF OBJECT_ID('tempdb..#HierarchyTEST') IS NOT NULL DROP TABLE #HierarchyTEST
GO
CREATE TABLE #HierarchyTEST
(
[Dimension Code] VARCHAR(50),
Code VARCHAR(50),
[Name] VARCHAR(50),
Indentation int,
);
-- # INSERT Begin
INSERT INTO #HierarchyGL ([No_],[Code],[Name]) VALUES ('GL1234','ACC0070', 'G L Test Acc 1');
INSERT INTO #HierarchyGL ([No_],[Code],[Name]) VALUES ('GL1235','ACC0587', 'G L Test Acc 2');
INSERT INTO #HierarchyGL ([No_],[Code],[Name]) VALUES ('GL1236','ACC0590', 'G L Test Acc 3');
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL', 'ACC0010', 'Level 1', 0);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0015', 'Level 2', 1);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0030', 'Level 3', 2);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0035', 'Level 4', 3);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0065', 'Level 3', 2);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0070', 'Level 4', 3);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0155', 'Level 1', 0);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0460', 'Level 2', 1);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0500', 'Level 3', 2);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0585', 'Level 3', 2);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0587', 'Level 4', 3);
INSERT INTO #HierarchyTEST ([Dimension Code],Code,[Name],Indentation) VALUES ('GL','ACC0590', 'Level 4', 3);
-- # INSERT End
IF OBJECT_ID('tempdb..#results') IS NOT NULL DROP TABLE #results
GO
CREATE TABLE #results
(
GLAccNo VARCHAR(50),
GLName VARCHAR(50),
DimCode VARCHAR(50),
DimName VARCHAR(50),
Indentation int
);
DECLARE
@gl_no VARCHAR(20),
@gl_name VARCHAR(50),
@dim_code VARCHAR(50),
@dim_name VARCHAR(50),
@indentation int;
DECLARE cursor_hierarchy CURSOR
FOR SELECT [No_], gl.Name, hl.Code, hl.Name
FROM #HierarchyGL gl
INNER JOIN #HierarchyTEST hl
ON gl.Code = hl.Code;
OPEN cursor_hierarchy;
FETCH NEXT FROM cursor_hierarchy INTO
@gl_no,
@gl_name,
@dim_code,
@dim_name;
WHILE @@FETCH_STATUS = 0 BEGIN
PRINT @gl_no;
-- get hierarchy
INSERT INTO #results
SELECT @gl_no, @gl_name, MAX(Code) AS [Code], MAX([Name]), Indentation
FROM (
SELECT
ROW_NUMBER() OVER(PARTITION BY Indentation ORDER BY Code , Indentation DESC) AS RowNr,
Code, [Dimension Code], Indentation, [Name]
FROM #HierarchyTEST
WHERE [Dimension Code] = 'GL'
AND Code <= @dim_code
) AS res
GROUP BY Indentation
FETCH NEXT FROM cursor_hierarchy INTO
@gl_no,
@gl_name,
@dim_code,
@dim_name;
END;
CLOSE cursor_hierarchy;
DEALLOCATE cursor_hierarchy;
SELECT * FROM #results;
И набор результатов
GLAccNo, GLName, DimCode, DimName, Indentation
GL1234, G L Test Acc 1, ACC0010, Level 1, 0
GL1234, G L Test Acc 1, ACC0015, Level 2, 1
GL1234, G L Test Acc 1, ACC0065, Level 3, 2
GL1234, G L Test Acc 1, ACC0070, Level 4, 3
GL1235, G L Test Acc 2, ACC0155, Level 1, 0
GL1235, G L Test Acc 2, ACC0460, Level 2, 1
GL1235, G L Test Acc 2, ACC0585, Level 3, 2
GL1235, G L Test Acc 2, ACC0587, Level 4, 3
GL1236, G L Test Acc 3, ACC0155, Level 1, 0
GL1236, G L Test Acc 3, ACC0460, Level 2, 1
GL1236, G L Test Acc 3, ACC0585, Level 3, 2
GL1236, G L Test Acc 3, ACC0590, Level 4, 3