PIVOT
Bu sorguyu gerçekleştirmek için işlevi kullanabilirsiniz . Cevabım hem Statik hem de dinamik bir versiyon içerecektir, çünkü bazen statik bir versiyon kullanarak anlamak daha kolaydır.
Statik Pivot, sütunlara dönüştürmek istediğiniz tüm değerleri sabit olarak kodladığınız zamandır.
-- first into into a #temp table the list of dates that you want to turn to columns
;with cte (datelist, maxdate) as
(
select min(arrivaldate) datelist, max(departuredate) maxdate
from BookingsPerPerson
union all
select dateadd(dd, 1, datelist), maxdate
from cte
where datelist < maxdate
)
select c.datelist
into #tempDates
from cte c
select *
from
(
select b.person_id, b.arrivaldate, b.departuredate,
d.datelist,
convert(CHAR(10), datelist, 120) PivotDate
from #tempDates d
left join BookingsPerPerson b
on d.datelist between b.arrivaldate and b.departuredate
) x
pivot
(
count(datelist)
for PivotDate in ([2012-01-01], [2012-01-02], [2012-01-03],
[2012-01-04], [2012-01-05], [2012-01-06] , [2012-01-07])
) p;
Sonuçlar (Bkz . Demo ile SQL Fiddle ):
PERSON_ID | ARRIVALDATE | DEPARTUREDATE | 2012-01-01 | 2012-01-02 | 2012-01-03 | 2012-01-04 | 2012-01-05 | 2012-01-06 | 2012-01-07
=====================================================================================================================================
123456 | 2012-01-01 | 2012-01-04 | 1 | 1 | 1 | 1 | 0 | 0 | 0
213415 | 2012-01-02 | 2012-01-07 | 0 | 1 | 1 | 1 | 1 | 1 | 1
Dinamik sürüm, sütunlara dönüştürülecek değerlerin listesini oluşturur:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
;with cte (datelist, maxdate) as
(
select min(arrivaldate) datelist, max(departuredate) maxdate
from BookingsPerPerson
union all
select dateadd(dd, 1, datelist), maxdate
from cte
where datelist < maxdate
)
select c.datelist
into #tempDates
from cte c
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(CHAR(10), datelist, 120))
from #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT person_id, arrivaldate, departuredate, ' + @cols + ' from
(
select b.person_id, b.arrivaldate, b.departuredate,
d.datelist,
convert(CHAR(10), datelist, 120) PivotDate
from #tempDates d
left join BookingsPerPerson b
on d.datelist between b.arrivaldate and b.departuredate
) x
pivot
(
count(datelist)
for PivotDate in (' + @cols + ')
) p '
execute(@query)
Sonuçlar aynıdır (bkz . Demo ile SQL Fiddle ):
PERSON_ID | ARRIVALDATE | DEPARTUREDATE | 2012-01-01 | 2012-01-02 | 2012-01-03 | 2012-01-04 | 2012-01-05 | 2012-01-06 | 2012-01-07
=====================================================================================================================================
123456 | 2012-01-01 | 2012-01-04 | 1 | 1 | 1 | 1 | 0 | 0 | 0
213415 | 2012-01-02 | 2012-01-07 | 0 | 1 | 1 | 1 | 1 | 1 | 1