Как выбрать всех сотрудников и отобразить их в строках по отделам? - PullRequest
0 голосов
/ 25 мая 2019

Ниже приведен пример данных, которыми я хочу манипулировать в своем операторе 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, но выбор одинаковых столбцов для каждого сотрудника в одной строке был проблемой для меня.

Также я хотел бы отметить, что в каждом отделе работает разное количество сотрудников. Таким образом, в некоторых строках отображается 6 сотрудников для этого отдела, а в других - 4 или 9

.

1 Ответ

0 голосов
/ 25 мая 2019

Это должно дать вам то, что вы ищете.

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;

Примечание ... Этот тип динамического кода не совсем интуитивно понятен для большинства людей. Поэтому, пожалуйста, не стесняйтесь задавать любые возникающие вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...