簡體   English   中英

如果每一列每個員工只有一個值,則SQL Server中的多行將變為單行

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM