我需要一些基本SQL查询的帮助。
我在SQL Server 2012中有一个表EmpID
,ManagerID
。我想构建一个查询来创建一个表格,该表格将数据显示为Emp ID
,Manager ID
,Manager 1
(最高层次结构),Manager 2
,Manager 3
,直到当前的经理ID。
我不知道从哪里开始,请指教。
谢谢
答案 0 :(得分:1)
以下情况应该至少让你朝着正确的方向前进......
对于想要一起玩的人,我已经发布了tfn_Tally和FirstName&的脚本。这里的姓氏表... 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
编辑...按名称拆分管理链...(使用原始#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