Опоздал на вечеринку, но решение с оптимальным планом запроса:
Пример данных
create table crimes(
CrimeID int, No_Of_Crimes int, CrimeDate datetime,
Violence char(1), Robbery char(1), ASB char(1));
insert crimes
select 1,1,'20110221','Y','Y','N' union all
select 2,3,'20110218','Y','N','N' union all
select 3,3,'20110223','N','N','Y' union all
select 4,2,'20110216','N','N','Y' union all
select 5,1,'20110217','N','N','Y';
Создание дополнительных данных - всего около 10240 строк в дополнение к 5 выше,каждые 5 - за 2 недели до предыдущего 5. Также создайте индекс, который поможет на crimedate
.
insert crimes
select crimeId+number*5, no_of_Crimes, DATEADD(wk,-number*2,crimedate),
violence, robbery, asb
from crimes, master..spt_values
where type='P'
create index ix_crimedate on crimes(crimedate)
С этого момента проверяйте выходные данные каждого, чтобы увидеть, куда это идет.Проверьте также план выполнения.
Стандартный Unpivot для разрыва категорий.
select CrimeID, No_Of_Crimes, CrimeDate, Category, YesNo
from crimes
unpivot (YesNo for Category in (Violence,Robbery,ASB)) upv
where YesNo='Y'
Примечания:
- Фильтр для YesNo фактически применяется ПОСЛЕ отмены вызова.Вы можете закомментировать его, чтобы увидеть.
Снять снова, но на этот раз выберите данные только за последнюю неделю и за эту неделю.
select CrimeID, No_Of_Crimes, Category,
Week = sign(datediff(d,CrimeDate,w.firstDayThisWeek)+0.1)
from crimes
unpivot (YesNo for Category in (Violence,Robbery,ASB)) upv
cross join (select DATEADD(wk, DateDiff(wk, 0, getdate()), 0)) w(firstDayThisWeek)
where YesNo='Y'
and CrimeDate >= w.firstDayThisWeek -7
and CrimeDate < w.firstDayThisWeek +7
Примечания:
(select DATEADD(wk, DateDiff(wk, 0, getdate()), 0)) w(firstDayThisWeek)
создает таблицу из одного столбца, в которой столбец содержит ключевую дату для этого запроса, являющуюся первым днем текущей недели (с использованием параметра DATEFIRST) - Фильтр для CrimeDate фактически применяется кОСНОВНОЙ СТОЛ до разворота.План проверки
Sign()
просто разбивает данные на 3 сегмента (-1 / 0 / + 1).Добавление +0.1 гарантирует, что есть только два сегмента -1 и + 1.
Последний запрос, поворот к которому / на прошлой неделе
select Category, isnull([1],0) ThisWeek, isnull([-1],0) LastWeek
from
(
select Category, No_Of_Crimes,
Week = sign(datediff(d,w.firstDayThisWeek,CrimeDate)+0.1)
from crimes
unpivot (YesNo for Category in (Violence,Robbery,ASB)) upv
cross join (select DATEADD(wk, DateDiff(wk, 0, getdate()), -1)) w(firstDayThisWeek)
where YesNo='Y'
and CrimeDate >= w.firstDayThisWeek -7
and CrimeDate < w.firstDayThisWeek +7
) p
pivot (sum(No_Of_Crimes) for Week in ([-1],[1])) pv
order by Category Desc
Вывод
Category ThisWeek LastWeek
--------- ----------- -----------
Violence 1 3
Robbery 1 0
ASB 3 3