【问题标题】:How do I order weekdays with row and column total in dynamic pivot如何在动态数据透视中使用行和列总计对工作日进行排序
【发布时间】:2015-02-06 02:46:55
【问题描述】:

我有一张表,其中有一些员工详细信息,例如 id、employeeid、workdate、taskid、hours、entrydate、entryby

另一张表有关于用户的基本信息,如名字,姓氏,emailid,密码

现在我想创建一个交叉表查询,我想在其中显示用户名和工作日以及员工的工作总小时数。 好吧,首先我想为此使用临时表,但我没有这样做,所以我一周中的每一天都使用这样的东西

select distinct employeeid ,sum(hours) as TotalHours ,'MONDAY' as Day into #Monday from Project_TimeSheet where  year(entrydate)='2014' and month(entrydate)='12' and datename(dw,entrydate)='MONDAY' group by employeeid

但对我来说这行不通。任何人请告诉我使用枢轴的查询我想要这样的结果

【问题讨论】:

    标签: sql-server sql-server-2008 pivot crosstab dynamic-pivot


    【解决方案1】:
    SELECT employeeid,
    SUM(CASE WHEN datename(dw,entrydate)='MONDAY' THEN hours END) as Monday,
    SUM(CASE WHEN datename(dw,entrydate)='TUESDAY' THEN hours END) as Tuesday,
    .....,
    sum(hours) as TotalHours
    FROM Project_TimeSheet
    WHERE  year(entrydate)='2014' and month(entrydate)='12'
    GROUP BY employeeid
    WITH ROLLUP
    

    【讨论】:

    • @Azadchouhan 在特定的一周内使用AND DATEPART ( wk , entrydate )=1..whatever
    • 请告诉我什么时候结束在这里使用?
    • @Azadchouhan 如果日期名称是星期一,它会计算小时数等等
    • @Azadchouhan ,您正在寻找整个月的记录,所以您将始终是 4-5 周数。
    • 我的一些需求更改,如果您对此有任何想法,请帮助我这是新问题的链接stackoverflow.com/questions/27501927/…
    【解决方案2】:

    这是示例表

    以及示例代码

    CREATE TABLE #TEMP (Name varchar(10), [DATE] datetime,
                TotalHours int)
    INSERT #TEMP VALUES 
    ('A','01/JAN/2014',10), 
    ('B','02/JAN/2014',20), 
    ('A','03/JAN/2014',20), 
    ('B','04/JAN/2014',30), 
    ('A','05/JAN/2014',40), 
    ('B','06/JAN/2014',50), 
    ('A','07/JAN/2014',60),
    ('A','08/JAN/2014',65),
    ('Z','07/JAN/2014',72),
    ('B','15/FEB/2014',70),
    ('B','16/FEB/2014',50), 
    ('A','17/FEB/2014',60),
    ('B','18/FEB/2014',70)
    

    在 Sql Server 中将星期一设置为一周的第一天

    SET DATEFIRST 1;
    

    将数据插入新表以对工作日进行排序并将总计作为最后一列

    SELECT DISTINCT DATENAME(WEEKDAY,[DATE])WK
    ,DATEPART(DW,[DATE]) WDNO
    INTO #ORDERTABLE
    FROM #TEMP
    UNION ALL
    SELECT 'TOTAL HOURS',8
    ORDER BY 2,1
    

    现在我们执行计算每个 Name 和 Weekdays 总数的逻辑,并将 row-Total 放在最后一行。

    SELECT 
    CASE Name WHEN 'TOTAL BY DAY' THEN 0
              ELSE DENSE_RANK() OVER(ORDER BY NAME DESC)
              END RNO,* 
    INTO #NEWTABLE
    FROM
    (
        SELECT CASE WHEN Name IS NULL THEN 'TOTAL BY DAY' ELSE Name END Name,
        CASE WHEN DATENAME(WEEKDAY,[DATE]) IS NULL THEN 'TOTAL HOURS' ELSE DATENAME(WEEKDAY,[DATE]) END WK,
        SUM(TotalHours)TotalHours   
        FROM #TEMP
        WHERE YEAR([DATE])=2014 AND DATENAME(MONTH,[DATE])='JANUARY'
        GROUP BY Name,DATENAME(WEEKDAY,[DATE])
        WITH CUBE
    )TAB
    ORDER BY RNO DESC
    

    #ORDERTABLE 表中选择不同的列

    DECLARE @cols NVARCHAR (MAX)
    
    SELECT @cols = COALESCE (@cols + ',[' + WK + ']', 
                   '[' + WK + ']')
                   FROM    (SELECT DISTINCT WK,WDNO FROM #ORDERTABLE) PV  
                   ORDER BY WDNO
    

    现在以RNO 旋转查询和排序(我们已应用逻辑将 Total 置于最后一行)

    DECLARE @query NVARCHAR(MAX)
    SET @query = '           
                  SELECT NAME,' + @cols + ' FROM 
                 (
                     SELECT * FROM #NEWTABLE
                 ) x
                 PIVOT 
                 (
                     SUM(TotalHours)
                     FOR WK IN (' + @cols + ')
                ) p       
                ORDER BY RNO DESC
                ' 
    
    EXEC SP_EXECUTESQL @query
    

    这是结果

    这里是 SQLFIDDLE http://sqlfiddle.com/#!3/655df/6 (如果加载时显示任何错误,只需单击 RUNSQL 按钮即可)

    这是一个更新,我们需要找到给定日期的那一周的开始日期和结束日期(在插入 #TEMP 表之后添加下面的内容)

    DECLARE @STARTDATE DATE;
    DECLARE @ENDDATE DATE;
    
    SELECT 
    @STARTDATE = CASE WHEN DATENAME(WEEKDAY,[DATE])='MONDAY' THEN [DATE]
          WHEN DATENAME(WEEKDAY,[DATE])='SUNDAY' THEN DATEADD(DAY,-6,[DATE]) 
          ELSE DATEADD(DAY,-datepart(dw,[DATE])+1,[DATE]) END 
    ,@ENDDATE = CASE WHEN DATENAME(WEEKDAY,[DATE])='MONDAY' THEN DATEADD(DAY,6,[DATE])
          WHEN DATENAME(WEEKDAY,[DATE])='SUNDAY' THEN [DATE]
          ELSE DATEADD(DAY,-datepart(dw,[DATE])+7,[DATE]) END 
    FROM #TEMP
    WHERE [DATE]=CAST('2014-01-06' AS DATE)
    

    并在WHERE条件中(在CUBE之前)使用上述变量,即,

    WHERE [DATE] BETWEEN @STARTDATE AND @ENDDATE
    

    【讨论】:

    • 你得到答案了吗? @Azad chouhan
    • 你能告诉我,如果任何用户输入任何日期作为搜索数据,我如何获取所有工作日,例如,如果任何用户输入 2014 年 12 月 10 日,那么我必须找到开始日期和结束日期使用此日期的那一周
    • 我已添加您的更新。检查时请更新我@Azad chouhan
    • 发生了什么?上述查询是否不符合您的规格或您的实际规格是什么?以下查询已使用图像为您的问题生成结果。发生了什么?这不是正确的答案吗? @Azad chouhan
    【解决方案3】:

    试试看,

        Declare @Year varchar(4)=2014
        Declare @Month varchar(2)=12
        Declare @Input datetime=@Year+'/'+@Month+'/'+'01'
        select @input
    
    
        select  employeeid 
        ,(Select sum(hours) as TotalHours from Project_TimeSheet M where year(entrydate)='2014' 
        and month(entrydate)='12' and datename(dw,entrydate)='MONDAY'  and m.employeeid=pts.employeeid  )'MONDAY' 
        from Project_TimeSheet PTS 
        ,(Select sum(hours) as TotalHours from Project_TimeSheet M where year(entrydate)='2014' 
        and month(entrydate)='12' and datename(dw,entrydate)='TUESDAY'  and m.employeeid=pts.employeeid  )'TUESDAY' 
        .....,
        from Project_TimeSheet PTS  
        where  year(entrydate)='2014' and month(entrydate)='12' and datename(dw,entrydate)='MONDAY' 
        group by employeeid
    
    OR 
    
    select 
    SUM(MONDAY)MONDAY,SUM(TUESDAY)TUESDAY
    ,........
    sum(hours)TotalHours
    from 
    (select  employeeid 
    ,case WHEN datename(dw,entrydate)='MONDAY' THEN hours else 0 end 'MONDAY'
    ,case WHEN datename(dw,entrydate)='TUESDAY' THEN hours else 0 end 'TUESDAY'
    ,.....
    ,hours
    from Project_TimeSheet PTS  
    where  year(entrydate)='2014' and month(entrydate)='12' and datename(dw,entrydate)='MONDAY' 
    )tbl
    group by employeeid
    

    【讨论】:

      猜你喜欢
      • 2021-10-28
      • 2020-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-31
      • 2017-11-12
      • 2019-07-07
      相关资源
      最近更新 更多