2013-04-09 3 views
12

Мне нужно группировать по вычисленному полю SQL Server 2005/2008.Как группировать по вычисленному полю

У меня есть следующий 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 

Вместо group by mwspp.DateDue мне нужно сгруппировать по результатам расчета. Является ли это возможным ?

Заранее спасибо

ответ

20

Конечно, просто добавьте тот же расчет на GROUP BY пункта:

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

Edit после комментария:

Как и все вопросы, касающиеся оптимизатора, ответ действительно «это зависит», но, скорее всего, это будет выполнено только один раз - вы увидите это в плане выполнения как Compute Scalar operato р.

Исходя из этого Вычислить скаляр, оптимизатор затем определит, как выполнить фактическую агрегацию.

Другие ответы здесь (CTE/subquery и т. Д.) Являются одинаково действительными, но на самом деле не меняют логики - в конечном итоге они будут выполнять аналогичные операции. SQL Server может относиться к ним иначе, но это маловероятно. Однако они помогут с удобочитаемостью.

Если вы беспокоитесь об эффективности, вы можете посмотреть несколько вариантов, например. настраивая вычисление как persisted computed column и используя это в индексе или добавляя промежуточные результаты во временную таблицу.

Единственный способ узнать наверняка - проверить статистику выполнения/IO при выполнении запроса на типичном наборе данных и посмотреть, удовлетворены ли вы производительностью; если нет, возможно, исследуя один из вышеуказанных вариантов.

+1

Спасибо, но не это немного дороже? или sql-сервер каким-то образом оптимизирует его для выполнения вычисления только один раз? – Jonny

+0

@ Jonny, я добавил несколько мыслей - самое лучшее, что можно сделать - это сделать снимок ваших данных и посмотреть, все ли в порядке - если нет, посмотрите на другие варианты повышения эффективности на тот момент. –

+0

Лично я ожидал бы, что производительность всех четырех ответов будет в значительной степени идентичной - основное отличие заключается в том, что используемые мной и Bluefeet методы более сухие, чем другие ответы, поскольку нам нужно было только один раз включить вычисление , –

12

Если вы хотите GROUP BY в DATEADD расчета, то вам нужно будет либо поместить эту формулу в пункте GROUP BY или вы можете обернуть запрос в другой 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

Есть несколько способов сделать так - один включает в себя использование КТР:

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

Просто поместите расчет в пункте GROUP BY:

Заменить

group by mwspp.DateDue 

К

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