SQL -PIVOT Таблица с использованием динамического значения - PullRequest
1 голос
/ 18 октября 2019

Я борюсь со сценарием, в котором я должен использовать таблицу PIVOT. Это

Ниже приведен источник данных. Первая исходная таблица содержит имя и номер сотрудника, а вторая таблица, которая является дочерней по отношению к первой, содержит Hiredate и TermDate с EmployeeId в качестве ForeignKey

2 таблиц.

Таблица сотрудников

ID     Name  EmployeeNo
----   ----  ----------
1      James   ABC
2      Allen   DEF

Таблица сведений о сотруднике

EmployeeId    HireDate      TerminationDate
----------    ---------     ---------------
     1        10/01/2001
     2        12/31/2017     01/01/2019     

Ожидаемый результат

JAMES     JAMES HIRE DATE    JAMES TERM DATE     ALLEN    ALLEN HIRE DATE    ALLEN TERM DATE
------    ---------------    ---------------     -----    ---------------    ---------------
ABC        10/01/2001                             DEF      12/31/2017         01/01/2019

Мне удалось принестив следующем порядке

   JAMES    ALLEN    JAMES HIRE DATE    ALLEN HIRE DATE   JAMES TERM DATE   ALLEN TERM DATE
   ------   -------   ---------------    ---------------   ---------------   --------------- 
     ABC     DEF       10/01/2001          12/31/2017                          01/01/2019

Но мой клиент настаивает на том, чтобы это было сделано

Ниже приведен код, который у меня есть до сих пор

CREATE TABLE #Employees (
    ID BIGINT
    ,[Name] VARCHAR(100)
    ,[EmployeeNo] VARCHAR(100)
    );

CREATE TABLE #EmployeeHireDetails (
    EmployeeId BIGINT
    ,HireDate DATETIME
    ,TermDate DATETIME
    );

INSERT INTO #Employees (ID,[Name],EmployeeNo) VALUES (1,'James','ABC')
INSERT INTO #Employees (ID,[Name],EmployeeNo) VALUES (2,'Allen','DEF')

INSERT INTO #EmployeeHireDetails (EmployeeId,HireDate,TermDate) VALUES (1,DATEADD(year, -2, GETDATE()),NULL)
INSERT INTO #EmployeeHireDetails (EmployeeId,HireDate,TermDate) VALUES (2,DATEADD(year, -1, GETDATE()),DATEADD(month, -5, GETDATE()))

DECLARE @EmpName NVARCHAR(MAX) = NULL
    ,@EmpHireDate NVARCHAR(MAX) = NULL
    ,@EmpTermDate NVARCHAR(MAX) = NULL

SELECT UPPER(E.Name) AS EmployeeName
    ,UPPER(E.Name) + ' ' + 'HIRE DATE' AS EmployeeHireDate
    ,UPPER(E.Name) + ' ' + 'TERM DATE' AS EmployeeTermDate
    ,EmployeeNo
    ,EH.EmployeeId
    ,EH.HireDate
    ,EH.TermDate
INTO #Emps
FROM #Employees E WITH (NOLOCK)
INNER JOIN #EmployeeHireDetails EH WITH (NOLOCK)
    ON E.ID = EH.EmployeeId

SET @EmpName = STUFF((
            SELECT ',' + QUOTENAME(EmployeeName)
            FROM #Emps
            FOR XML PATH('')
                ,TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

DECLARE @EmpNameQry NVARCHAR(MAX)  

SET @EmpNameQry = 'SELECT *                 
   FROM (            
   SELECT E.EmployeeNo           
     ,UPPER(E.EmployeeName) EmployeeName            
     --,E.EmployeeId AS EmpName_EmployeeId          
    FROM #Emps E            
    INNER JOIN #Employees EId            
     ON E.EmployeeId = EId.ID               
    ) p            
   Pivot(Max(EmployeeNo) FOR EmployeeName IN (' + @EmpName + ')) AS Pivot_table'

EXEC sp_executesql @EmpNameQry

DECLARE @EmpHireDateQry NVARCHAR(MAX)

SET @EmpHireDate = STUFF((
            SELECT ',' + QUOTENAME(EmployeeHireDate)
            FROM #Emps
            FOR XML PATH('')
                ,TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SET @EmpHireDateQry = 'SELECT *                 
   FROM (            
  SELECT E.HireDate           
    ,EmployeeHireDate               
    FROM #Emps E            
    INNER JOIN #Employees EId            
     ON E.EmployeeId = EId.ID                
    ) p            
   Pivot(Max(HireDate) FOR EmployeeHireDate IN (' + @EmpHireDate + ')) AS Pivot_table2'

EXEC sp_executesql @EmpHireDateQry


DECLARE @EmpTermDateQry NVARCHAR(MAX)

SET @EmpTermDate = STUFF((
            SELECT ',' + QUOTENAME(EmployeeTermDate)
            FROM #Emps
            FOR XML PATH('')
                ,TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '')


SET @EmpHireDateQry = 'SELECT *                 
   FROM (            
  SELECT E.TermDate           
    ,EmployeeTermDate               
    FROM #Emps E            
    INNER JOIN #Employees EId            
     ON E.EmployeeId = EId.ID                
    ) p            
   Pivot(Max(TermDate) FOR EmployeeTermDate IN (' + @EmpTermDate + ')) AS Pivot_table3'

EXEC sp_executesql @EmpHireDateQry

DROP TABLE #EmployeeHireDetails
DROP TABLE #Employees
DROP TABLE #Emps

1 Ответ

0 голосов
/ 19 октября 2019

Можно использовать CTE и условную агрегацию. Имена столбцов жестко закодированы. Возможно, вам придется использовать динамический запрос для генерации имен столбцов, когда вы не можете жестко кодировать имена столбцов.

with jt as
(
select t1.Name, t1.EmployeeNo, t2.HireDate, t2.TerminationDate
from employee t1
inner join employeeDetails t2 on t2.EmployeeID = t1.ID
)
select
    max(case when Name = 'James' then EmployeeNo end) as JAMES,
    max(case when Name = 'James' then HireDate end) as 'JAMES HIRE DATE',
    max(case when Name = 'James' then TerminationDate end) as 'JAMES TERMINATION DATE',
    max(case when Name = 'Allen' then EmployeeNo end) as ALLEN,
    max(case when Name = 'Allen' then HireDate end) as 'ALLEN HIRE DATE',
    max(case when Name = 'Allen' then TerminationDate end) as 'ALLEN TERMINATION DATE'
from jt
...