日期:2014-05-18  浏览次数:20693 次

求sql ......
现在求一条sql语句:
  表结构如下:
  id name status workday remark
 
1001 张三 上班 2011-11-10
1002 李四 上班 2011-11-10
1003 王五 上班 2011-11-10
1004 张三 上班 2011-11-11
1005 李四 请假 2011-11-11
1006 王五 上班 2011-11-11

现在这个表结构需要统计出来的报表样式如下(报表统计周期为上月的26号到本月的25号)

姓名 25号 26号 .....1号 2号.. 10号 11 号 ... 25号  
张三 .... 上班 上班 ...
李四 .... 上班 请假 ...
王五 .... 上班 上班 ...

也就是说需要把纵向的workday (从上一个月的26号到本月的25号所有天)横响过来 显示,循环取出某个月度的所有员工考勤详情报表
 
 


求转换语句......
 
 


------解决方案--------------------
行列转换。N多。
------解决方案--------------------
SQL code
--> --> (Roy)生成測試數據
 
if not object_id('Tempdb..#T') is null
    drop table #T
Go
Create table #T([id] int,[name] nvarchar(2),[status] nvarchar(2),[workday] Datetime)
Insert #T
select 1001,N'张三',N'上班','2011-11-10' union all
select 1002,N'李四',N'上班','2011-11-10' union all
select 1003,N'王五',N'上班','2011-11-10' union all
select 1004,N'张三',N'上班','2011-11-11' union all
select 1005,N'李四',N'请假','2011-11-11' union all
select 1006,N'王五',N'上班','2011-11-11'
Go
declare @dt1 datetime,@dt2 datetime,@dt3 datetime
set @dt1='2011-11-25'
set @dt2=dateadd(m,-1,@dt1)+1
set @dt3=@dt2

declare @s nvarchar(4000)
set @s=''
while @dt1>=@dt2
Select   @s=@s+N','+quotename(rtrim(Day(@dt2))+'号')+N'=max(case when Day([workday])=N'+quotename(Day(@dt2),'''')+N' then [status]  end)',@dt2=@dt2+1

--顯示生成語句
print N'select [name]'+@s+N' from #T where [workday] between '''+convert(varchar(10),@dt3,120)+''' and '''+convert(varchar(10),@dt1,120)+'''  group by [name]'

exec(N'select [name]'+@s+N' from #T where [workday] between '''+@dt3+''' and '''+@dt1+''' group by [name]')


/*
name    26号    27号    28号    29号    30号    31号    1号    2号    3号    4号    5号    6号    7号    8号    9号    10号    11号    12号    13号    14号    15号    16号    17号    18号    19号    20号    21号    22号    23号    24号    25号
李四    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    上班    请假    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
王五    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    上班    上班    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
张三    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    上班    上班    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
*/

------解决方案--------------------
SQL code
Create table tb([id] int,[name] nvarchar(2),[status] nvarchar(2),[workday] Datetime)
Insert tb
select 1001,N'张三',N'上班','2011-11-10' union all
select 1002,N'李四',N'上班','2011-11-10' union all
select 1003,N'王五',N'上班','2011-11-10' union all
select 1004,N'张三',N'上班','2011-11-11' union all
select 1005,N'李四',N'请假','2011-11-11' union all
select 1006,N'王五',N'上班','2011-11-11'
go

declare @sql varchar(8000)
set @sql = 'select name '
select @sql = @sql + ' , max(case convert(varchar(10),workday,120) when ''' + dt + ''' then status else '''' end) [' + dt + ']'
from 
(
  select 
    convert(varchar(10),dateadd(dd,num,cast(convert(varchar(8),dateadd(mm,-1,getdate()),120)+'26' as datetime)),120) dt
  from 
    (select isnull((select count(1) from sysobjects where id<t.id),0) as num from sysobjects t) a
  where
    dateadd(dd,num,cast(convert(varchar(8),dateadd(mm,-1,getdate()),120)+'26' as datetime))<= convert(varchar(8),getdate(),120) + '25'
) as a
set @sql = @sql + ' from tb where workday bet