基本的なSQLクエリについては助けが必要です。列内に階層を構築するためのSQLクエリ
私はSQL Server 2012にテーブルEmpID
、ManagerID
を持っています。現在のマネージャIDまでEmp ID
、Manager ID
、Manager 1
(最高階層)、Manager 2
、Manager 3
というデータを表示するテーブルを作成するクエリを作成したいと思います。
どこから始めたらよいかわからないので、アドバイスをお願いします。
はありがとう基本的なSQLクエリについては助けが必要です。列内に階層を構築するためのSQLクエリ
私はSQL Server 2012にテーブルEmpID
、ManagerID
を持っています。現在のマネージャIDまでEmp ID
、Manager ID
、Manager 1
(最高階層)、Manager 2
、Manager 3
というデータを表示するテーブルを作成するクエリを作成したいと思います。
どこから始めたらよいかわからないので、アドバイスをお願いします。
はありがとう、最低でも一緒に演奏したい人のため
は、私がtfn_Tallyとのスクリプトを公開した...あなたは正しい方向に進んで取得する必要があり、次のここでの姓& LastNameのテーブル... https://www.dropbox.com/s/cagt1875bkuahwy/Employee%20Hiearchy%20Test%20Objects.sql?dl=0
IF OBJECT_ID('tempdb..#TestData', 'U') IS NULL
BEGIN -- DROP TABLE #TestData
CREATE TABLE #TestData (
EmployeeID INT NOT NULL PRIMARY KEY CLUSTERED,
FirstName VARCHAR(30) NOT NULL,
LastName VARCHAR(30) NOT NULL,
ManagerID INT NOT NULL
);
INSERT #TestData (EmployeeID, FirstName, LastName, ManagerID)
SELECT
EmployeeID = t.n,
fnx.FirstName,
lnx.LastName,
ManagerID = CASE WHEN t.n = 1 THEN 0 ELSE m.ManagerID END
FROM
dbo.tfn_Tally(50, 1) t
CROSS APPLY (VALUES (ABS(CHECKSUM(NEWID())) % ISNULL(NULLIF(t.n - 1, 0), 1) + 1)) m (ManagerID)
CROSS APPLY (VALUES (ABS(CHECKSUM(NEWID())) % 500 + 1, ABS(CHECKSUM(NEWID())) % 1000 + 1, ABS(CHECKSUM(NEWID())) % 2)) n (fn, ln, g)
CROSS APPLY (
SELECT
fn.FirstName
FROM
dbo.FirstNames fn --WITH (FORCESEEK) --, INDEX (0))
WHERE
n.fn = fn.RankNo
AND CASE WHEN n.g = 0 THEN 'M' ELSE 'F' END = fn.Gender
) fnx
CROSS APPLY (
SELECT
ln.LastName
FROM
dbo.LastNames ln --WITH (FORCESEEK) --, INDEX (0))
WHERE
n.ln = ln.RankNo
) lnx
END;
-- ===========================================================
WITH
cte_Recursion AS (
SELECT
td.EmployeeID,
td.FirstName,
td.LastName,
NodeLevel = 1,
ManagementChain = CAST(td.EmployeeID AS VARCHAR(8000))
FROM
#TestData td
WHERE
td.ManagerID = 0
UNION ALL
SELECT
td.EmployeeID,
td.FirstName,
td.LastName,
NodeLevel = r.NodeLevel + 1,
ManagementChain = CAST(CONCAT(r.ManagementChain, ' > ', td.EmployeeID) AS VARCHAR(8000))
FROM
cte_Recursion r
JOIN #TestData td
ON r.EmployeeID = td.ManagerID
)
SELECT
*
FROM
cte_Recursion r
ORDER BY
r.EmployeeID;
結果...
EmployeeID FirstName LastName NodeLevel ManagementChain
----------- ------------------------------ ------------------------------ ----------- --------------------------------------------------
1 Alexa Wang 1 1
2 Amy Cardenas 2 1 > 2
3 Drake Lloyd 2 1 > 3
4 Jasmin Moses 3 1 > 3 > 4
5 Shayla Massey 4 1 > 3 > 4 > 5
6 Steven Cole 3 1 > 2 > 6
7 Rafael Pittman 4 1 > 2 > 6 > 7
8 Trenton Mendez 5 1 > 3 > 4 > 5 > 8
9 Khalil Bray 3 1 > 3 > 9
10 Edward Hubbard 4 1 > 3 > 4 > 10
11 Ricky Harrison 4 1 > 3 > 9 > 11
12 Joe Velasquez 5 1 > 3 > 4 > 5 > 12
13 Henry Kaiser 4 1 > 3 > 4 > 13
14 Weston Grimes 5 1 > 3 > 9 > 11 > 14
15 Esther Rogers 3 1 > 2 > 15
16 Kenneth Price 5 1 > 3 > 4 > 5 > 16
17 Jesse Lambert 6 1 > 3 > 4 > 5 > 16 > 17
18 Jenna Perry 4 1 > 2 > 6 > 18
19 Joselyn Bowman 3 1 > 3 > 19
20 Scarlett Green 5 1 > 3 > 4 > 5 > 20
21 Lena Wolfe 3 1 > 2 > 21
22 Asher Baird 3 1 > 2 > 22
23 Adam Woodward 3 1 > 3 > 23
24 Adam Reed 5 1 > 3 > 9 > 11 > 24
25 Kendall Conway 6 1 > 3 > 9 > 11 > 24 > 25
26 Charlotte Gibson 7 1 > 3 > 9 > 11 > 24 > 25 > 26
27 Hayley Levy 4 1 > 2 > 21 > 27
28 Kade Hogan 8 1 > 3 > 9 > 11 > 24 > 25 > 26 > 28
29 Juan Moreno 4 1 > 2 > 21 > 29
30 Bridget Ochoa 4 1 > 2 > 21 > 30
31 Tate Gonzales 2 1 > 31
32 Ryder Marsh 5 1 > 3 > 4 > 5 > 32
33 Gavin Craig 5 1 > 2 > 6 > 18 > 33
34 Aniya Matthews 4 1 > 3 > 9 > 34
35 Angie Rollins 6 1 > 3 > 4 > 5 > 32 > 35
36 Hanna Golden 7 1 > 3 > 4 > 5 > 16 > 17 > 36
37 Jimmy Hendrix 6 1 > 3 > 4 > 5 > 32 > 37
38 Leah Blackwell 6 1 > 2 > 6 > 18 > 33 > 38
39 Brady Vaughn 7 1 > 3 > 4 > 5 > 16 > 17 > 39
40 Milo Wright 2 1 > 40
41 Simon Lamb 6 1 > 3 > 9 > 11 > 24 > 41
42 Miguel Kennedy 6 1 > 2 > 6 > 18 > 33 > 42
43 Kayleigh Todd 7 1 > 2 > 6 > 18 > 33 > 38 > 43
44 Allisson Townsend 7 1 > 3 > 9 > 11 > 24 > 25 > 44
45 Ty Haynes 5 1 > 3 > 9 > 11 > 45
46 Angel Gay 6 1 > 2 > 6 > 18 > 33 > 46
47 Reese Marshall 6 1 > 3 > 4 > 5 > 12 > 47
48 Maria Howard 8 1 > 3 > 4 > 5 > 16 > 17 > 36 > 48
49 Ella Mcgee 9 1 > 3 > 9 > 11 > 24 > 25 > 26 > 28 > 49
50 Cheyanne Estes 4 1 > 2 > 6 > 50
EDIT ...名前で分割管理チェーン...(オリジナル#TestDataを使用)
IF OBJECT_ID('tempdb..#RecursionResults', 'U') IS NOT NULL
DROP TABLE #RecursionResults;
GO
WITH
cte_Recursion AS (
SELECT
td.EmployeeID,
EmployeeName = CONCAT(td.FirstName + ' ', td.LastName),
NodeLevel = 1,
ManagementChain = CAST(CAST(CONCAT(td.FirstName + ' ', td.LastName) AS BINARY(61)) AS VARBINARY(MAX))
FROM
#TestData td
WHERE
td.ManagerID = 0
UNION ALL
SELECT
td.EmployeeID,
EmployeeName = CONCAT(td.FirstName + ' ', td.LastName),
NodeLevel = r.NodeLevel + 1,
ManagementChain = CAST(CONCAT(r.ManagementChain, CAST(CONCAT(td.FirstName + ' ', td.LastName) AS BINARY(61))) AS VARBINARY(MAX))
FROM
cte_Recursion r
JOIN #TestData td
ON r.EmployeeID = td.ManagerID
)
SELECT
r.EmployeeID,
r.EmployeeName,
r.NodeLevel,
r.ManagementChain
INTO #RecursionResults
FROM
cte_Recursion r
ORDER BY
r.EmployeeID;
----------------------------------
DECLARE
@MaxNode INT,
@MgtColumList NVARCHAR(4000),
@sql NVARCHAR(4000),
@DeBug BIT = 0; -- 1=PRINT @sql... 2=EXEC @sql
SELECT @MaxNode = MAX(rr.NodeLevel) FROM #RecursionResults rr;
SELECT
@MgtColumList = CONCAT(@MgtColumList, N',
MgrLevel_', t.n + 1, N' = CAST(SUBSTRING(rr.ManagementChain, ', (t.n * 61) + 1, N', ', 61, N') AS VARCHAR(61))')
FROM
dbo.tfn_Tally(@MaxNode, 0) t;
SET @sql = CONCAT(N'
SELECT
rr.EmployeeID,
rr.EmployeeName,
rr.NodeLevel',
@MgtColumList, N'
FROM
#RecursionResults rr;');
IF @DeBug = 1
BEGIN
PRINT(@sql);
END;
ELSE
BEGIN
EXEC sys.sp_executesql @sql;
END;
結果サンプル...あなたはすでに
EmployeeID EmployeeName NodeLevel MgrLevel_1 MgrLevel_2 MgrLevel_3
----------- ------------------------------------------------------------- ----------- ------------------------------------------------------------- ------------------------------------------------------------- -------------------------------------------------------------
1 Theodore Cain 1 Theodore Cain
2 Julianna Sanders 2 Theodore Cain Julianna Sanders
3 Caroline Wilkinson 3 Theodore Cain Julianna Sanders Caroline Wilkinson
4 Eleanor Hancock 3 Theodore Cain Julianna Sanders Eleanor Hancock
5 Casey Ware 2 Theodore Cain Casey Ware
6 Jacoby Lyons 4 Theodore Cain Julianna Sanders Caroline Wilkinson
7 Jaden Stout 2 Theodore Cain Jaden Stout
8 Reece Weeks 5 Theodore Cain Julianna Sanders Caroline Wilkinson
9 Kyleigh Frazier 5 Theodore Cain Julianna Sanders Caroline Wilkinson
10 Nasir Wong 3 Theodore Cain Casey Ware Nasir Wong
11 Sarah Rivas 4 Theodore Cain Julianna Sanders Eleanor Hancock
これは素晴らしいです。再帰文を使用してレベル/ノードを取得できました。階層内のすべてのマネージャーを従業員名の横に複数の列として上から下に表示する方法があります。 – Nat85
ねえ...それはできる。私が仕事を辞めると、今晩遅くにコードを更新します。 –
@ Nataraj - 私の元の回答が更新されました。 –
何を研究し、および/または試してみましたか? –
研究https://blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/ –
私はまったく同じクエリを試しましたマネージャーIDが UNION NULL IS WHERE MyCTE と同じように(従業員 FROMのEmpID、姓、姓、マネージャーID を選択...記事で言及された全ての SELECTのEmpID、姓、姓、マネージャーID 従業員 INNER FROM MyCTE ON Employee.ManagerIDを登録しよう= MyCTE.EmpID ここでEmployee.ManagerIDはNULLではありません) SELECT * FROM MyCTEしかし、これはマネージャレベルのようなIDレベルのみを互いに隣接する列ではありません – Nat85