我有一张桌子,其中有一些员工详细信息,如id,employeeid,workdate,taskid,hours,entrydate,entryby
另一个表有关于用户的基本信息,如firstname,lastname,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
但对我来说这不起作用。任何人请告诉我使用数据透视表的查询我希望结果像这样
答案 0 :(得分: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
答案 1 :(得分:1)
以下是示例表
和示例代码
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
现在我们为每个名称和工作日计算总计的逻辑,并在最后一行中显示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按钮,它将起作用)
这是一个更新,我们需要在给定日期找到该周的Startdate和EndDate(在插入#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
答案 2 :(得分:0)
试试,
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