web-dev-qa-db-fra.com

Comment grouper par un champ calculé

J'ai besoin de regrouper par un champ calculé dans SQL Server 2005/2008.

J'ai le sql suivant:

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

Au lieu de group by mwspp.DateDue J'ai besoin de grouper par le résultat du calcul. C'est possible ?

Merci d'avance

23
Jonny

Bien sûr, ajoutez simplement le même calcul au GROUP BY clause:

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)))

Modifier après le commentaire:

Comme toutes les questions concernant l'optimiseur, la réponse est vraiment "cela dépend", mais très probablement, elle ne sera effectuée qu'une seule fois - vous verrez cela dans le plan d'exécution comme un calcul scalaire opérateur.

Sur la base de cette opération Compute Scalar , l'optimiseur décidera alors comment effectuer l'agrégation réelle.

Les autres réponses ici (CTE/sous-requête, etc.) sont toutes également valables, mais ne changent pas vraiment la logique - en fin de compte, elles effectueront des opérations similaires. SQL Server peut les traiter différemment, mais c'est peu probable. Cependant, ils aideront à la lisibilité.

Si vous vous inquiétez de l'efficacité, vous pouvez envisager quelques options, par exemple configurer le calcul comme colonne calculée persistante et l'utiliser dans un index, ou ajouter des résultats intermédiaires dans une table temporaire.

La seule façon de savoir avec certitude est d'inspecter les statistiques du plan d'exécution/d'E/S lors de l'exécution de la requête sur un ensemble de données typique et de voir si vous êtes satisfait des performances; sinon, étudiez peut-être l'une des options ci-dessus.

32
Ian Preston

Si tu veux GROUP BY le calcul dateadd, alors vous devrez soit placer cette formule dans le GROUP BY clause ou vous pouvez encapsuler votre requête dans un autre 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
18
Taryn

Il y a plusieurs façons de le faire - l'une consiste à utiliser un 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
4
user359040

Placez simplement le calcul dans le GROUP BY clause:

Remplacer

group by mwspp.DateDue

À

group by dateadd(day, -7, Convert(DateTime, mwspp.DateDue) + (7 - datepart(weekday, mwspp.DateDue)))
2
Praveen Nambiar