我如何 select 所有员工并将他们按部门显示在行中?
How do I select all employees and display them in rows per department?
下面是我要在 select 语句中操作的数据示例。
Employee ID | Department ID | FirstName | LastName | Role
----------------------------------------------------------------
1 | 1 | Jack | Skeleton | Cashier
2 | 2 | Rachel | Sparrow | Cashier
3 | 1 | Samuel | Kite | Bagger
4 | 2 | Arnold | Herrera | Bagger
5 | 1 | Edwin | Molina | Bagger
下面是我想要显示数据的方式。
Dept ID| Emp ID | Role | Emp ID | Role | EmpID | Role |
-----------------------------------------------------------------
1 | 1 |Cashier | 3 |Bagger | 5 | Bagger|
2 | 2 |Cashier | 4 |Bagger |
我已经尝试过 Pivot,但是 select为同一行中的每个员工设置相同的列对我来说是个问题。
我还想指出每个部门的员工人数不同。因此,某些行会显示该部门的 6 名员工,而其他行会显示 4 或 9
这应该能找到您要找的东西。
SET NOCOUNT ON;
GO
--================================================================
-- create some test data...
IF OBJECT_ID('tempdb..#Department', 'U') IS NOT NULL
BEGIN DROP TABLE #Department; END;
CREATE TABLE #Department (
DepartmentID INT NOT NULL PRIMARY KEY,
DepartmentName VARCHAR(50) NOT NULL
);
INSERT #Department (DepartmentID, DepartmentName) VALUES
(1, 'Department 1'), (2, 'Department 2');
IF OBJECT_ID('tempdb..#Employee', 'U') IS NOT NULL
BEGIN DROP TABLE #Employee; END;
CREATE TABLE #Employee (
EmployeeID INT NOT NULL PRIMARY KEY,
DepartmentID INT NOT NULL,
FirstName VARCHAR(20) NOT NULL,
LastName VARCHAR(20) NOT NULL,
[Role] VARCHAR(20) NOT NULL
);
INSERT #Employee (EmployeeID, DepartmentID, FirstName, LastName, [Role]) VALUES
(1, 1, 'Jack', 'Skeleton', 'Cashier'),
(2, 2, 'Rachel', 'Sparrow', 'Cashier'),
(3, 1, 'Samuel', 'Kite', 'Bagger'),
(4, 2, 'Arnold', 'Herrera', 'Bagger'),
(5, 1, 'Edwin', 'Molina', 'Bagger');
--================================================================
-- begin the actual solution...
DECLARE
@sql NVARCHAR(MAX) = N'',
@debug BIT = 0; -- choose 0 the execute the dynamic sql & 1 to print it.
WITH
cte_columns_needed AS (
SELECT DISTINCT
rn = ROW_NUMBER() OVER (PARTITION BY e.DepartmentID ORDER BY e.EmployeeID)
FROM
#Employee e
)
SELECT TOP (10000)
@sql = CONCAT(@sql, N',
', QUOTENAME(N'EmpID_' + x.rn), N' = MAX(CASE WHEN ern.rn = ', cn.rn, N' THEN ern.EmployeeID END),
', QUOTENAME(N'Role_' + x.rn), N' = MAX(CASE WHEN ern.rn = ', cn.rn, N' THEN ern.Role END)'
)
FROM
cte_columns_needed cn
CROSS APPLY ( VALUES (CONVERT(NVARCHAR(10), cn.rn)) ) x (rn)
ORDER BY
cn.rn;
SET @sql = CONCAT(N'
SELECT
[DeptID] = ern.DepartmentID',
@sql, N'
FROM (
SELECT
e.EmployeeID,
e.DepartmentID,
e.Role,
rn = ROW_NUMBER() OVER (PARTITION BY e.DepartmentID ORDER BY e.EmployeeID)
FROM
#Employee e
) ern
GROUP BY
ern.DepartmentID
ORDER BY
ern.DepartmentID;'
);
IF @debug = 1
BEGIN
PRINT(@sql);
END;
ELSE
BEGIN
EXEC sys.sp_executesql @sql;
END;
注意...对于大多数人来说,这种类型的动态代码并不十分直观。所以,请随时提出任何问题。
下面是我要在 select 语句中操作的数据示例。
Employee ID | Department ID | FirstName | LastName | Role
----------------------------------------------------------------
1 | 1 | Jack | Skeleton | Cashier
2 | 2 | Rachel | Sparrow | Cashier
3 | 1 | Samuel | Kite | Bagger
4 | 2 | Arnold | Herrera | Bagger
5 | 1 | Edwin | Molina | Bagger
下面是我想要显示数据的方式。
Dept ID| Emp ID | Role | Emp ID | Role | EmpID | Role |
-----------------------------------------------------------------
1 | 1 |Cashier | 3 |Bagger | 5 | Bagger|
2 | 2 |Cashier | 4 |Bagger |
我已经尝试过 Pivot,但是 select为同一行中的每个员工设置相同的列对我来说是个问题。
我还想指出每个部门的员工人数不同。因此,某些行会显示该部门的 6 名员工,而其他行会显示 4 或 9
这应该能找到您要找的东西。
SET NOCOUNT ON;
GO
--================================================================
-- create some test data...
IF OBJECT_ID('tempdb..#Department', 'U') IS NOT NULL
BEGIN DROP TABLE #Department; END;
CREATE TABLE #Department (
DepartmentID INT NOT NULL PRIMARY KEY,
DepartmentName VARCHAR(50) NOT NULL
);
INSERT #Department (DepartmentID, DepartmentName) VALUES
(1, 'Department 1'), (2, 'Department 2');
IF OBJECT_ID('tempdb..#Employee', 'U') IS NOT NULL
BEGIN DROP TABLE #Employee; END;
CREATE TABLE #Employee (
EmployeeID INT NOT NULL PRIMARY KEY,
DepartmentID INT NOT NULL,
FirstName VARCHAR(20) NOT NULL,
LastName VARCHAR(20) NOT NULL,
[Role] VARCHAR(20) NOT NULL
);
INSERT #Employee (EmployeeID, DepartmentID, FirstName, LastName, [Role]) VALUES
(1, 1, 'Jack', 'Skeleton', 'Cashier'),
(2, 2, 'Rachel', 'Sparrow', 'Cashier'),
(3, 1, 'Samuel', 'Kite', 'Bagger'),
(4, 2, 'Arnold', 'Herrera', 'Bagger'),
(5, 1, 'Edwin', 'Molina', 'Bagger');
--================================================================
-- begin the actual solution...
DECLARE
@sql NVARCHAR(MAX) = N'',
@debug BIT = 0; -- choose 0 the execute the dynamic sql & 1 to print it.
WITH
cte_columns_needed AS (
SELECT DISTINCT
rn = ROW_NUMBER() OVER (PARTITION BY e.DepartmentID ORDER BY e.EmployeeID)
FROM
#Employee e
)
SELECT TOP (10000)
@sql = CONCAT(@sql, N',
', QUOTENAME(N'EmpID_' + x.rn), N' = MAX(CASE WHEN ern.rn = ', cn.rn, N' THEN ern.EmployeeID END),
', QUOTENAME(N'Role_' + x.rn), N' = MAX(CASE WHEN ern.rn = ', cn.rn, N' THEN ern.Role END)'
)
FROM
cte_columns_needed cn
CROSS APPLY ( VALUES (CONVERT(NVARCHAR(10), cn.rn)) ) x (rn)
ORDER BY
cn.rn;
SET @sql = CONCAT(N'
SELECT
[DeptID] = ern.DepartmentID',
@sql, N'
FROM (
SELECT
e.EmployeeID,
e.DepartmentID,
e.Role,
rn = ROW_NUMBER() OVER (PARTITION BY e.DepartmentID ORDER BY e.EmployeeID)
FROM
#Employee e
) ern
GROUP BY
ern.DepartmentID
ORDER BY
ern.DepartmentID;'
);
IF @debug = 1
BEGIN
PRINT(@sql);
END;
ELSE
BEGIN
EXEC sys.sp_executesql @sql;
END;
注意...对于大多数人来说,这种类型的动态代码并不十分直观。所以,请随时提出任何问题。