[英]Multiple rows in to single row in SQL Server if each column has only one value per employee
怎么做請幫忙。
我有以下數據。 這是一周的數據樣本。 我想要每個EmployeeName / CrewID單行 (除非單個日期中有Employee的2個值)。
如果原始數據是這樣的:
2018-08-05 2018-08-06 2018-08-07 2018-08-08 2018-08-09 2018-08-10 2018-08-11 CrewID EmployeeName
------------ ------------ ------------ ------------ ------------ ------------ ------------ -------- ----------------
NULL 174 173 172 171 NULL NULL 9 Kanhaiya
NULL NULL NULL NULL NULL 178 NULL 9 Kanhaiya
NULL 174 173 172 171 NULL NULL 8 Santanu Maulik
NULL NULL NULL NULL NULL 178 NULL 8 Santanu Maulik
上述原件的輸出應按每人單行排列,如下所示。
2018-08-05 2018-08-06 2018-08-07 2018-08-08 2018-08-09 2018-08-10 2018-08-11 CrewID EmployeeName
------------ ------------ ------------ ------------ ------------ ------------ ------------ -------- ----------------
NULL 174 173 172 171 178 NULL 9 Kanhaiya
NULL 174 173 172 171 178 NULL 8 Santanu Maulik
但是對於某些條件,仍然可以將每個員工的數據分散到多行中,例如,如果該員工在單個日期中具有多個值,例如。 “2018年8月10日”
如果原始數據是這樣的:
2018-08-05 2018-08-06 2018-08-07 2018-08-08 2018-08-09 2018-08-10 2018-08-11 CrewID EmployeeName
------------ ------------ ------------ ------------ ------------ ------------ ------------ -------- --------------
NULL 174 173 172 171 NULL NULL 9 Kanhaiya
NULL NULL NULL NULL 163 178 NULL 9 Kanhaiya
上述原始數據的輸出應如下所示。
2018-08-05 2018-08-06 2018-08-07 2018-08-08 2018-08-09 2018-08-10 2018-08-11 CrewID EmployeeName
------------ ------------ ------------ ------------ ------------ ------------ ------------ -------- --------------
NULL 174 173 172 171 178 NULL 9 Kanhaiya
NULL NULL NULL NULL 163 NULL NULL 9 Kanhaiya
我設法通過存儲過程獲取數據。
這是存儲過程的主要邏輯部分:
ALTER PROCEDURE [dbo].[GetDataForCustomWeekViewReport]
@Week AS INT,
@typeOfData AS VARCHAR(10)
AS
BEGIN
DECLARE @weekAdjustAdd INT
SET NOCOUNT ON;
SET DATEFIRST 7;
SET @weekAdjustAdd = (@Week - 1) * 7
DECLARE @SQLQuery AS NVARCHAR(MAX)
DECLARE @PivotColumns AS NVARCHAR(MAX)
-----------------------------
-- Get unique values of pivot column
SELECT
@PivotColumns= COALESCE(@PivotColumns + ',','') + QUOTENAME(WORKDAYS)
FROM
(SELECT DISTINCT WORKDAYS
FROM
(SELECT
DATEADD(DAY, @weekAdjustAdd, CAST(DATEADD(WEEK, DATEDIFF(DAY, -1, GETDATE()) / 7, -1) AS date)) AS WORKDAYS
UNION
SELECT
DATEADD(DAY, @weekAdjustAdd, CAST(DATEADD(WEEK, DATEDIFF(DAY, -1, GETDATE()) / 7, 0) AS date)) AS WORKDAYS
UNION
SELECT
DATEADD(DAY, @weekAdjustAdd, CAST(DATEADD(WEEK, DATEDIFF(DAY, -1, GETDATE()) / 7, 1) AS date)) AS WORKDAYS
UNION
SELECT
DATEADD(DAY, @weekAdjustAdd, CAST(DATEADD(WEEK, DATEDIFF(DAY, -1, GETDATE()) / 7, 2) AS date)) AS WORKDAYS
UNION
SELECT
DATEADD(DAY, @weekAdjustAdd, CAST(DATEADD(WEEK, DATEDIFF(DAY, -1, GETDATE()) / 7, 3) AS date)) AS WORKDAYS
UNION
SELECT
DATEADD(DAY, @weekAdjustAdd, CAST(DATEADD(WEEK, DATEDIFF(DAY, -1, GETDATE()) / 7, 4) AS date)) AS WORKDAYS
UNION
SELECT
DATEADD(DAY, @weekAdjustAdd, CAST(DATEADD(WEEK, DATEDIFF(DAY, -1, GETDATE()) / 7, 5) AS date)) AS WORKDAYS
) i) AS PivotExample
IF (@typeOfData = 'f')
BEGIN
--Get unique values of pivot column
--Create the dynamic query with all the values for
--pivot column at runtime
--',JOBID, JobInfo,CrewID, EmployeeName,Color
-- ,JI.INumber + '' - '' + JI.ITitle AS JobInfo, M.Color,
SET @SQLQuery =
N'
DECLARE @Week AS int
DECLARE @weekAdjustAdd int
SET @Week=1
SET DATEFIRST 7;
SET @weekAdjustAdd = (@Week - 1) * 7
SELECT ' + @PivotColumns + ', CrewID, EmployeeName
FROM (
SELECT J.ID AS JOBID, C.ID AS CrewID ,c.CrewName AS EmployeeName , JI.ID AS JOBINSTANCE_ID,JI.WORKDAYS
FROM [dbo].[Job] J
LEFT JOIN [dbo].[Job_Instances] JI ON J.ID=JI.JOBID
LEFT JOIN [dbo].[Instance_Employee_Relation] IER ON JI.ID=IER.JobInstanceID
LEFT JOIN [dbo].[Crew] C ON C.Id = IER.EMPLOYEEID
INNER JOIN [dbo].[Manager] M ON M.Id = JI.ManagerID
INNER JOIN dbo.JobType JT ON JT.ID = JI.JobTypeID
WHERE ( C.EmployeeTypeID=1 OR C.EmployeeTypeID IS NULL) AND JI.TYPE = ''F'' AND JI.WORKDAYS BETWEEN DATEADD(DAY,'+CONVERT(VARCHAR(20) ,@weekAdjustAdd)+', CAST(DATEADD(WEEK, DATEDIFF(DAY, -1, GETDATE()) / 7, -1) AS date)) AND DATEADD(DAY,'+ CONVERT(VARCHAR(20) ,@weekAdjustAdd)+', CAST(DATEADD(WEEK, DATEDIFF(DAY, -1, GETDATE()) / 7, 5) AS date))
)i
PIVOT( SUM(JobInstance_ID)
FOR [WORKDAYS] IN (' + @PivotColumns + ')) AS P ORDER BY CASE WHEN EmployeeName IS NULL THEN 1 ELSE 0 END, EmployeeName'
--Execute dynamic query
EXEC sp_executesql @SQLQuery
END
UPDATE
@Ven試圖幫助我並做得很好,但是如果我每個員工只有2行,但是如果我每個員工都有2行以上,他的答案將奏效。
原始數據
2018-08-05 2018-08-06 2018-08-07 2018-08-08 2018-08-09 2018-08-10 2018-08-11 CrewID EmployeeName
------------ ------------ ------------ ------------ ------------ ------------ ------------ -------- ----------------
NULL 174 173 172 171 NULL NULL 9 Kanhaiya
NULL NULL NULL NULL NULL 178 NULL 9 Kanhaiya
NULL NULL NULL NULL 183 182 NULL 8 Santanu Maulik
NULL NULL NULL NULL NULL 178 NULL 8 Santanu Maulik
NULL 174 173 172 171 NULL NULL 8 Santanu Maulik
@Ven 解決方案的輸出 (對於CrewID 8,因為他有3行,所以它不起作用,但是對於CrewID 9,因為他具有2行,所以沒有工作。)
CrewID EmployeeName 2018-08-05 2018-08-06 2018-08-07 2018-08-08 2018-08-09 2018-08-10 2018-08-11
-------- ---------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------
8 Santanu Maulik NULL NULL NULL NULL NULL 178 NULL
8 Santanu Maulik NULL NULL NULL NULL 183 182 NULL
8 Santanu Maulik NULL 174 173 172 171 NULL NULL
9 Kanhaiya NULL 174 173 172 171 178 NULL
通過3個不同的步驟來解決這個問題,以滿足需求。 沒有其他骯臟的方式做到這一點:)
1)通過自連接(左連接)獲取表中的上一行和下一行
2)Case表達式從下一行獲取值,其中第一行的值為null,第二行的值為非null
2)case表達式如果兩行相等,則第二行為空值
DECLARE @table TABLE (
id INT identity(1, 1)
,[2018-08-05] INT
,[2018-08-06] INT
,[2018-08-07] INT
,[2018-08-08] INT
,[2018-08-09] INT
,[2018-08-10] INT
,[2018-08-11] INT
,CrewID INT
,EmployeeName VARCHAR(20)
)
INSERT @table
------------ ------------ ------------ ------------ ------------ ------------ ------------ -------- ----------------
SELECT NULL
,174
,173
,172
,171
,NULL
,NULL
,9
,'Kanhaiya'
UNION ALL
SELECT NULL
,NULL
,NULL
,NULL
,163
,178
,NULL
,9
,'Kanhaiya'
UNION ALL
SELECT NULL
,174
,173
,172
,171
,NULL
,NULL
,8
,'Santanu Maulik'
UNION ALL
SELECT NULL
,NULL
,NULL
,NULL
,NULL
,178
,NULL
,8
,'Santanu Maulik';
腳本:
WITH CTE
AS (
SELECT rownum = ROW_NUMBER() OVER (
PARTITION BY p.crewid ORDER BY p.crewID
)
,p.*
FROM @table p
)
,ct2
AS (
SELECT TOP 100 PERCENT cte.CrewID
,cte.employeename
,CASE WHEN cte.[2018-08-05] IS NULL THEN nex.[2018-08-05] ELSE cte.[2018-08-05] END [2018-08-05]
,CASE WHEN cte.[2018-08-06] IS NULL THEN nex.[2018-08-06] ELSE cte.[2018-08-06] END [2018-08-06]
,CASE WHEN cte.[2018-08-07] IS NULL THEN nex.[2018-08-07] ELSE cte.[2018-08-07] END [2018-08-07]
,CASE WHEN cte.[2018-08-08] IS NULL THEN nex.[2018-08-08] ELSE cte.[2018-08-08] END [2018-08-08]
,CASE WHEN cte.[2018-08-09] IS NULL THEN nex.[2018-08-09] ELSE cte.[2018-08-09] END [2018-08-09]
,CASE WHEN cte.[2018-08-10] IS NULL THEN nex.[2018-08-10] ELSE cte.[2018-08-10] END [2018-08-10]
,CASE WHEN cte.[2018-08-11] IS NULL THEN nex.[2018-08-11] ELSE cte.[2018-08-11] END [2018-08-11]
FROM CTE
LEFT JOIN CTE prev ON prev.rownum = CTE.rownum - 1
LEFT JOIN CTE nex ON nex.rownum = CTE.rownum + 1
ORDER BY cte.CrewID
)
,ct3
AS (
SELECT DISTINCT CrewID
,EmployeeName
,CASE WHEN [2018-08-05] = LEAD([2018-08-05]) OVER (
PARTITION BY crewid ORDER BY [2018-08-05]
) THEN NULL ELSE [2018-08-05] END [2018-08-05]
,CASE WHEN [2018-08-06] = LEAD([2018-08-06]) OVER (
PARTITION BY crewid ORDER BY [2018-08-06]
) THEN NULL ELSE [2018-08-06] END [2018-08-06]
,CASE WHEN [2018-08-07] = LEAD([2018-08-07]) OVER (
PARTITION BY crewid ORDER BY [2018-08-07]
) THEN NULL ELSE [2018-08-07] END [2018-08-07]
,CASE WHEN [2018-08-08] = LEAD([2018-08-08]) OVER (
PARTITION BY crewid ORDER BY [2018-08-08]
) THEN NULL ELSE [2018-08-08] END [2018-08-08]
,CASE WHEN [2018-08-09] = LEAD([2018-08-09]) OVER (
PARTITION BY crewid ORDER BY [2018-08-09]
) THEN NULL ELSE [2018-08-09] END [2018-08-09]
,CASE WHEN [2018-08-10] = LEAD([2018-08-10]) OVER (
PARTITION BY crewid ORDER BY [2018-08-10]
) THEN NULL ELSE [2018-08-10] END [2018-08-10]
,CASE WHEN [2018-08-11] = LEAD([2018-08-11]) OVER (
PARTITION BY crewid ORDER BY [2018-08-11]
) THEN NULL ELSE [2018-08-11] END [2018-08-11]
FROM ct2
)
SELECT *
FROM ct3
WHERE isnull([2018-08-05], 0) + isnull([2018-08-06], 0) + isnull([2018-08-07], 0) + isnull([2018-08-08], 0) + isnull([2018-08-09], 0) + isnull([2018-08-10], 0) + isnull([2018-08-11], 0) > 0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.