このタイプのデータ変換は、PIVOT
. SQL Server 2005 以降では、これを実行する機能があります。
事前に値がわかっている場合は、次のようなクエリをハードコーディングできます。
select *
from
(
select id,
[Emp_ID],
cast([ontime] as date) ontime
from test
) src
pivot
(
count(id)
for ontime in ([2013-02-11], [2013-02-12], [2013-02-13])
) piv
SQL Fiddle with Demoを参照してください。
変換する列の数が不明な場合は、動的 SQL を使用する必要があります。WHERE
特定の日付のみを検索する句を使用して、これをさらにフィルタリングできます。
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast([ontime] as date))
from test
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT emp_id,' + @cols + ' from
(
select Emp_ID pivId,
[Emp_ID],
cast([ontime] as date) ontime
from test
) x
pivot
(
count(pivId)
for ontime in (' + @cols + ')
) p '
execute(@query)
SQL Fiddle with Demoを参照してください。
希望する日付が返されることを保証したい場合は、最初に日付のリストを生成できます。したがって、動的 SQL スクリプト全体は次のようになります。
declare @startdate datetime
declare @enddate datetime
set @startdate = '2013-02-11'
set @enddate = '2013-02-13'
;with cte (startdate) as
(
select @startdate
union all
select DATEADD(dd, 1, startdate)
from cte
where DATEADD(dd, 1, startdate) <= @enddate
)
select *
into #tempDates
from cte;
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast(startdate as date))
from #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT emp_id,' + @cols + ' from
(
select Emp_ID pivId,
[Emp_ID],
cast([ontime] as date) ontime
from test
) x
pivot
(
count(pivId)
for ontime in (' + @cols + ')
) p '
execute(@query)
SQL Fiddle with Demoを参照してください。これは結果を返します:
| EMP_ID | 2013-02-11 | 2013-02-12 | 2013-02-13 |
-------------------------------------------------
| 1 | 2 | 0 | 1 |
| 2 | 1 | 0 | 1 |
| 3 | 0 | 0 | 1 |
編集#1、すべての従業員を含める場合は、別のテーブルでJOINを使用する必要があり、コードは次のようになります。
declare @startdate datetime
declare @enddate datetime
set @startdate = '2013-02-11'
set @enddate = '2013-02-13'
;with cte (startdate) as
(
select @startdate
union all
select DATEADD(dd, 1, startdate)
from cte
where DATEADD(dd, 1, startdate) <= @enddate
)
select *
into #tempDates
from cte;
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast(startdate as date))
from #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT emp_id, Emp_name,' + @cols + ' from
(
select e.Emp_ID pivId,
e.[Emp_ID],
e.Emp_name,
cast([ontime] as date) ontime
from Emp_Table e
left join test t
on e.emp_id = t.emp_id
) x
pivot
(
count(pivId)
for ontime in (' + @cols + ')
) p '
execute(@query)
デモで SQL Fiddle を参照してください