我确信这对于核心SQL爱好者来说不是一个难题,但我需要一些帮助。这适用于SQL Server 2000(继承的项目!)。
我有一张工资清单表,如下所示:
EmployeeID | EffectiveDate | Salary
1 | 2/1/2011 | 500
1 | 6/1/2011 | 600
1 | 12/1/2011 | 650
我需要创建一个查询,在一年中按月输出这些工资。所以输出就像
EmployeeID | Jan | Feb | Mar | Apr | Apr | May | Jun | Jul | Aug | Sept | Oct | Nov | Dec
1 | 500 | 500 | 500 | 500 | 500 | 500 | 600 | 600 | 600 | 600 | 600 | 600 | 650
我知道必须有一种方法可以有效地使用SQL,我似乎无法做到正确。显然,我会用SQL命名上面的月份列,例如 SELECT EmployeeID,'Jan'AS Jan,'Feb'AS Feb等,但由于我正在寻找范围,所以其余的陈述更难。
答案 0 :(得分:3)
由于您使用的是SQL Server 2000,因此它没有PIVOT
函数,因此您必须使用聚合函数和CASE
语句来复制它。与此类似:
select employeeid,
sum(case when DatePart(Month, EffectiveDate) = 1 then Salary end) as Jan,
sum(case when DatePart(Month, EffectiveDate) = 2 then Salary end) as Feb,
sum(case when DatePart(Month, EffectiveDate) = 3 then Salary end) as Mar,
sum(case when DatePart(Month, EffectiveDate) = 4 then Salary end) as Apr,
sum(case when DatePart(Month, EffectiveDate) = 5 then Salary end) as May,
sum(case when DatePart(Month, EffectiveDate) = 6 then Salary end) as Jun,
sum(case when DatePart(Month, EffectiveDate) = 7 then Salary end) as Jul,
sum(case when DatePart(Month, EffectiveDate) = 8 then Salary end) as Aug,
sum(case when DatePart(Month, EffectiveDate) = 9 then Salary end) as Sep,
sum(case when DatePart(Month, EffectiveDate) = 10 then Salary end) as Oct,
sum(case when DatePart(Month, EffectiveDate) = 11 then Salary end) as Nov,
sum(case when DatePart(Month, EffectiveDate) = 12 then Salary end) as Dec
from yourtable
group by employeeid
编辑,基于您上面的评论,从一个月到下一个月的值,这是一个可能适合您的解决方案。
declare @query as nvarchar(max) = '',
@rowcount as int = 1,
@pivotrow as int,
@currentMonthSalary as int = 0,
@priorMonthSalary as int = 0,
@employeeid int
select distinct effectivedate
into #colspivot
from yourtable
while @rowcount <= 12 -- loop thru each month
begin
set @pivotrow = (select top 1 datepart(month, effectivedate)
from #colspivot
order by datepart(month, effectivedate))
select @currentMonthSalary = salary, @employeeid = EmployeeID
from yourtable
where datepart(month, effectivedate) = @pivotrow
if @pivotrow = @rowcount
begin
insert into FinalData (employeeid, effectivemonth, salary)
select @employeeid, cast(DateName(month, DateAdd(month, @pivotrow, 0) -1) as varchar(3)), @currentMonthSalary
set @query = @query + ', sum(case when effectivemonth = ''' + cast(DateName(month, DateAdd(month, @pivotrow, 0) -1) as varchar(3)) + '''
then ' + cast(@currentMonthSalary as varchar(10)) + ' end) as '+ cast(DateName(month, DateAdd(month, @pivotrow, 0) -1) as varchar(3))
delete from #colsPivot where datepart(month, effectivedate) = @pivotRow
set @priorMonthSalary = @currentMonthSalary
end
else
begin
insert into FinalData (employeeid, effectivemonth, salary)
select @employeeid, cast(DateName(month, DateAdd(month, @rowcount, 0) -1) as varchar(3)), @priorMonthSalary
set @query = @query + ', sum(case when effectivemonth = ''' + cast(DateName(month, DateAdd(month, @rowcount, 0) -1) as varchar(3)) + '''
then ' + cast(@priorMonthSalary as varchar(10)) + ' end) as '+cast(DateName(month, DateAdd(month, @rowcount, 0) -1) as varchar(3))
end
if @rowcount <= 12
set @rowcount = @rowcount + 1
end
set @query = 'select employeeid '+ @query
+ ' from FinalData group by employeeid;'
exec(@query)
见SQL Fiddle with Demo。我创建了一个新表FinalData
来存储每个月的数据,同时我循环创建sql语句。
答案 1 :(得分:2)
尝试此查询:
Select EmployeeID, [Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec]
From
(
Select EmployeeID, CAST(DateName(MONTH,EffectiveDate) as varchar(3)) as Mon, Salary
From Employees
) as SourceTable
PIVOT
(
Sum(Salary)
For Mon in ( [Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec] )
) as PivotTable
它与您在输出样本中显示的结果产生完全相同的结果。