我需要按 SQL Server 2005/2008 列中的计算字段进行分组。
我有以下疑问:
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
我需要按计算结果进行分组。可以吗?
当然,只需将相同的计算添加到
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)))
评论后编辑:
像所有有关优化器的问题一样,答案实际上是“这取决于”,但很可能它只会执行一次 - 您将在执行计划中看到它作为 Compute Scalar 运算符。
基于此计算标量操作,优化器将决定如何执行实际聚合。
这里的其他答案(CTE/子查询等)都同样有效,但并没有真正改变逻辑 - 最终它们将执行类似的操作。 SQL Server 可能会以不同的方式对待它们,但这不太可能。然而,它们将有助于提高可读性。
如果您担心效率,您可以考虑几个选项,例如将计算设置为持久计算列并在索引中使用它,或者将临时结果添加到临时表中。
真正确定的唯一方法是在典型数据集上运行查询时检查执行计划/IO 统计信息,看看您是否对性能感到满意;如果没有,也许调查上述选项之一。
如果您想要
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
有多种方法可以实现这一点 - 一种方法涉及使用 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;
只需将计算放在
GROUP BY
子句中即可:
更换
group by mwspp.DateDue
至
group by dateadd(day, -7, Convert(DateTime, mwspp.DateDue) + (7 - datepart(weekday, mwspp.DateDue)))
添加
CROSS APPLY
解决方案以确保完整性。
使用
CROSS APPLY
可以多次重复使用计算值,而无需重复表达式。
正如其他答案中所述,它不太可能影响性能,更多的是一种风格选择。
select c.DateCalc, sum(mwspp.QtyRequired)
from manufacturingweekshortagepartpurchasing mwspp
cross apply (dateadd(day, -7, convert(datetime, mwspp.DateDue) + (7 - datepart(weekday, mwspp.DateDue)))) c (DateCalc)
where mwspp.buildScheduleSimID = 10109 and mwspp.partID = 8366
group by c.DateCalc
order by c.DateCalc;