2013-04-09 18 views
12

Muszę grupować według pola obliczeniowego w SQL Server 2005/2008.Jak grupować według pola obliczeniowego

Mam następujący sql:

select dateadd(day, -7, Convert(DateTime, mwspp.DateDue) + (7 - datepart(weekday, mwspp.DateDue))), 
sum(mwspp.QtyRequired) 
from manufacturingweekshortagepartpurchasing mwspp 
where mwspp.buildScheduleSimID = 10109 and mwspp.partID = 8366 
group by mwspp.DateDue 
order by mwspp.DateDue 

Zamiast group by mwspp.DateDue muszę do grupy o wyniku obliczeń. Czy to możliwe ?

góry dzięki

Odpowiedz

20

Jasne, wystarczy dodać taką samą kalkulację do GROUP BY klauzuli:

select dateadd(day, -7, Convert(DateTime, mwspp.DateDue) + (7 - datepart(weekday, mwspp.DateDue))), 
sum(mwspp.QtyRequired) 
from manufacturingweekshortagepartpurchasing mwspp 
where mwspp.buildScheduleSimID = 10109 and mwspp.partID = 8366 
group by dateadd(day, -7, Convert(DateTime, mwspp.DateDue) + (7 - datepart(weekday, mwspp.DateDue))) 
order by dateadd(day, -7, Convert(DateTime, mwspp.DateDue) + (7 - datepart(weekday, mwspp.DateDue))) 

Edytuj po Komentarz:

jak wszystkie pytania dotyczące optymalizatora, odpowiedź brzmi: naprawdę "to zależy", ale najprawdopodobniej zostanie wykonane tylko raz - zobaczysz to w planie wykonawczym jako Compute Scalar operato r.

W oparciu o tę operację Obliczenie skalarne, optymalizator zdecyduje, jak wykonać rzeczywistą agregację.

Inne odpowiedzi tutaj (CTE/podzapytanie, itp.) Są równie ważne, ale tak naprawdę nie zmieniają logiki - ostatecznie będą wykonywać podobne operacje. SQL Server może traktować je inaczej, ale jest to mało prawdopodobne. Pomogą one jednak w czytelności.

Jeśli martwisz się o wydajność, możesz spojrzeć na kilka opcji, np. konfigurowanie obliczeń jako persisted computed column i używanie go w indeksie lub dodawanie wyników tymczasowych do tabeli tymczasowej.

Jedyny sposób, aby naprawdę wiedzieć na pewno, to sprawdzić statystyki planu wykonania/zamówienia reklamowego podczas uruchamiania kwerendy na typowym zestawie danych i zobaczyć, czy jesteś zadowolony z wydajności; jeśli nie, być może badając jedną z powyższych opcji.

+1

Dzięki, ale nie jest to nieco droższe? czy serwer sql jakoś optymalizuje go do wykonywania obliczeń tylko raz? – Jonny

+0

@ Jonny, dodałem kilka przemyśleń - najlepiej zrobić to, aby zrobić zdjęcie na swoich danych i sprawdzić, czy wszystko jest w porządku - jeśli nie, spójrz na inne opcje, aby poprawić efektywność w tym momencie. –

+0

Osobiście oczekiwałbym, że wyniki wszystkich czterech odpowiedzi będą w zasadzie identyczne - główna różnica polega na tym, że podejście (-a) zastosowane przeze mnie i Bluefeeta jest bardziej SUCHE niż inne odpowiedzi, ponieważ musieliśmy uwzględnić obliczenia tylko raz . –

12

Jeśli chcesz GROUP BY z DateAdd obliczenia, wtedy albo trzeba umieścić tę formułę w klauzuli GROUP BY lub można owinąć zapytanie w inny SELECT:

select DateCalc, 
    sum(QtyRequired) TotalQty 
from 
(
    select mwspp.DateDue, 
    dateadd(day, -7, Convert(DateTime, mwspp.DateDue) + (7 - datepart(weekday, mwspp.DateDue))) DateCalc, 
    mwspp.QtyRequired 
    from manufacturingweekshortagepartpurchasing mwspp 
    where mwspp.buildScheduleSimID = 10109 
    and mwspp.partID = 8366 
) src 
group by DateCalc 
order by DateCalc 
3

Istnieje kilka sposobów takiego postępowania - jeden polega na użyciu CTE:

with cte as 
(select m.*, 
     dateadd(day, -7, Convert(DateTime, DateDue) + (7 - datepart(weekday, DateDue))) datecalc 
from manufacturingweekshortagepartpurchasing m) 
select datecalc, sum(QtyRequired) 
from cte 
where buildScheduleSimID = 10109 and partID = 8366 
group by datecalc 
order by datecalc 
2

Wystarczy umieścić obliczenia w klauzuli GROUP BY:

Wymień

group by mwspp.DateDue 

Do

group by dateadd(day, -7, Convert(DateTime, mwspp.DateDue) + (7 - datepart(weekday, mwspp.DateDue))) 
Powiązane problemy