我有以下查询,它为每位员工每天赚取一笔钱。
现在我想将这些日期行显示为列。我当前的查询及其输出如下。
declare @StartDate datetime,@EndDate datetime,@CompanyId int
set @StartDate='01/01/2013'
set @EndDate='01/31/2013'
set @CompanyId=3
;with d(date) as (
select cast(@StartDate as datetime)
union all
select date+1
from d
where date < @EndDate
)
select distinct d.date CDate,E.EmployeeId,Earning.EarningDescription,Earning.EarningId
,E.FirstName + ' ' + E.MiddleName + ' ' + E.LastName AS EmployeeName
from d,Employee as E
inner join Earning on E.CompanyId=Earning.CompanyId
where E.CompanyId=@CompanyId and Earning.IsOnTimeCard=1 and Earning.IsHourly=1
order by EmployeeId,CDate,EarningId
此输出需要使用pivot进行转换。我试过看一些例子 枢纽。
根据建议的解决方案来寻找解决方案,现在我有了这个查询并且给了我错误
declare @StartDate datetime,@EndDate datetime,@CompanyId int,@cols AS NVARCHAR(MAX),@query AS NVARCHAR(MAX)
set @StartDate='01/01/2013'
set @EndDate='01/31/2013'
set @CompanyId=3
declare @WorkingDays Table
(
WDate smalldatetime
)
;with d(date) as (
select cast(@StartDate as datetime)
union all
select date+1
from d
where date < @EndDate
)
insert into @WorkingDays select d.date from d
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(wd.WDate)
FROM @WorkingDays wd
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
PRINT @cols
set @query = '
SELECT
*
FROM
(
select distinct WDate CDate,E.EmployeeId,Earning.EarningDescription,Earning.EarningId
from @WorkingDays ,Employee as E
inner join Earning on E.CompanyId=Earning.CompanyId
where E.CompanyId=@CompanyId and Earning.IsOnTimeCard=1 and Earning.IsHourly=1
) src
PIVOT
(
MIN(src.EarningId)
FOR src.CDate IN ('+@cols+')
) AS PivotedView '
PRINT (@query)
execute(@query)
,错误如下:
Must declare the table variable "@WorkingDays".
答案 0 :(得分:1)
SQL Server PIVOT子句不支持动态列,看起来您需要动态列列表。使用PIVOT执行此操作的唯一方法是构造动态SQL语句,旋转当时所需的日期列表,然后执行此SQL。
中提供了类似的解决方案答案 1 :(得分:0)
declare @StartDate datetime,@EndDate datetime,@CompanyId int,@cols AS NVARCHAR(MAX),@query AS NVARCHAR(MAX)
set @StartDate='01/01/2013'
set @EndDate='01/31/2013'
set @CompanyId=3
Create table #t
(
WDate smalldatetime
)
;with d(date) as (
select cast(@StartDate as datetime)
union all
select date+1
from d
where date < @EndDate
)
insert into #t select d.date from d
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(wd.WDate)
FROM #t wd
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
PRINT @cols
set @query = '
SELECT
*
FROM
(
select distinct WDate CDate,E.EmployeeId,Earning.EarningDescription,Earning.EarningId
,E.FirstName +' + '''' + ' ''' + '+ E.MiddleName +' + '''' + ' ''' + '+ E.LastName AS EmployeeName
from #t ,Employee as E
inner join Earning on E.CompanyId=Earning.CompanyId
where E.CompanyId='+ CAST (@CompanyId as nvarchar(50)) +' and Earning.IsOnTimeCard=1 and Earning.IsHourly=1
) src
PIVOT
(
MIN(EarningDescription)
FOR src.CDate IN ('+@cols+')
) AS PivotedView order by EmployeeId,EarningId '
PRINT (@query)
execute(@query)
drop table #t
答案 2 :(得分:-2)
尝试以下查询
select '01/01/2013' Cdate, 19 EmployeeID,'regular' EarningDescription, 21 EarningID, CAST('rebecca smith' as varchar(20)) Employeename INTO #temp union all select
'01/01/2013', 19,'OverTime', 21, 'rebecca smith' union all select
'01/01/2013', 19,'DoubleOvertime', 22, 'rebecca smith' union all select
'01/01/2013', 19,'regular', 23, 'rebecca smith' union all select
'01/01/2013', 19,'vacation', 104, 'rebecca smith' union all select
'01/01/2013', 19,'Travel', 105, 'rebecca smith' union all select
'02/01/2013', 19,'regular', 21, 'rebecca smith' union all select
'02/01/2013', 19,'OverTime', 21, 'rebecca smith' union all select
'02/01/2013', 19,'DoubleOvertime', 22, 'rebecca smith' union all select
'02/01/2013', 19,'regular', 23, 'rebecca smith' union all select
'02/01/2013', 19,'vacation', 104, 'rebecca smith' union all select
'02/01/2013', 19,'Travel', 105, 'rebecca smith' union all select
'03/01/2013', 19,'regular', 21, 'rebecca smith' union all select
'03/01/2013', 19,'OverTime', 21, 'rebecca smith' union all select
'03/01/2013', 19,'DoubleOvertime', 22, 'rebecca smith' union all select
'03/01/2013', 18,'regular', 23, 'ganesh' union all select
'03/01/2013', 18,'vacation', 104, 'ganesh' union all select
'03/01/2013', 18,'Travel', 105, 'ganesh'
declare @StartDate datetime,@EndDate datetime,@CompanyId int
set @StartDate='01/01/2013'
set @EndDate='01/31/2013'
set @CompanyId=3
;with d(date) as (
select cast(@StartDate as datetime) as date
union all
select date+1
from d
where date < @EndDate
)
select * INTO #dates FROM d
declare @dates varchar(max), @datecolumn varchar(max)
select @dates=COALESCE(@dates+',','')+'['+convert(varchar(MAX),date,103)+']' from #dates
print @dates
EXEC(
' SELECT * FROM (
select distinct convert(varchar(MAX),CDate,103) CDate,E.EmployeeId,e.EarningDescription,e.EarningId
, EmployeeName
from #temp e
) as x
PIVOT (
MAX(EmployeeName)
FOR CDate IN ('+@dates+')
) as pvt order by EmployeeId,EarningId')
如果它对您有用,请不要忘记回答。