SQL Server查询生成动态员工考勤报告

时间:2013-05-31 08:42:56

标签: sql sql-server

我有一张表来存储员工出勤率,其中包含以下列:

  • id:int,pk
  • StaffName:varchar
  • CompanyName:varchar
  • isPresent:varchar
  • 日期:datetime

如何编写一个能够出席一个月的查询?

例如:为公司XYZ生成4月份的报告,该报告看起来应该是

StaffName       1 2 3 4 5 6 7 8 9....up to last day of month
--------------------------------------------------------------
John lenon      p p p a p a a p a....
Bob Dylan       a a a p p p p p a....
Keith Moon      p p p p a p a p p....

2 个答案:

答案 0 :(得分:0)

您可以使用PIVOT功能将日期转换为列(此处是一个快速而肮脏的示例,您可以检查日期格式和顺序):

SELECT StaffName, [0], [1], [2], [3], [4] and so on...
FROM
(SELECT StaffName, isPresent, date FROM myTable) AS SourceTable
PIVOT
(
MAX(isPresent)
FOR date IN ([0], [1], [2], [3], [4] and so on...)
) AS PivotTable;

答案 1 :(得分:0)

对于动态查询,这可能有点棘手。对于表格:

CREATE TABLE [dbo].[attendance](
    [id] [int] NOT NULL,
    [StaffName] [varchar](100) NULL,
    [CompanyName] [varchar](100) NULL,
    [isPresent] [char](1) NULL,
    [date] [datetime] NULL,
    PRIMARY KEY CLUSTERED  ( [id] ASC )
)
go 

以下脚本生成'pivot-compatible'脚本,其中包含天数作为列

--report params
DECLARE @month int, @year int, @lastDay int
set @month = 1 
set @year = 2012


-- calculations
DECLARE @startDate datetime, @endDate datetime
SET @startDate =  convert(varchar, @year) + '-' + convert(varchar, @month) + '-1'
set @endDate = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@startDate)+1,0))
set @lastDay =  day(@endDate) --last day of month

print('showing data from ' + convert(varchar, @startDate) + ' to ' + convert(varchar, @endDate))
print('original report')
SELECT StaffName, isPresent, day([date]) as day FROM attendance
where [date] between @startDate and @endDate

declare @day int
set @day = 2


declare @days varchar(max)
set @days = '[1]'
WHILE (@day <= @lastDay)
BEGIN
   set @days = @days + ',[' + convert(varchar, @day) + ']'
   set @day = @day + 1
END

-- select @days

declare @query varchar(max)

set @query = '
SELECT StaffName, ' + @days  +
'
FROM
(SELECT StaffName, isPresent, day(date) as day FROM attendance) AS SourceTable
PIVOT
(
MAX(isPresent)
FOR day IN ( ' + @days + ')' + '
) AS PivotTable;'

--select @query

print('pivoted report')    
exec(@query)