我有这样的查询:
select date, count(*)
from inflow
where date >= dateadd(year, -2, getdate())
group by date
order by date
我需要排除星期六和星期日的日期,而是将其计数添加到下一个星期一。最好的方法是什么?我是否需要排除周六,周日和周一,然后通过加入其他查询将它们添加进来?上面的查询是简化版本,这是一个相对较大的查询,因此我需要牢记效率。
答案 0 :(得分:1)
嗯,这是一种蛮力的方法:
select date,
(case when datename(weekday, date) = 'Monday')
then cnt + cnt1 + cnt2
else cnt
end) as cnt
from (select date, count(*) as cnt,
lag(count(*), 1, 0) over (order by date) as prev_cnt,
lag(count(*), 2, 0) over (order by date) as prev_cnt2
from inflow
where date >= dateadd(year, -2, getdate())
group by date
) d
where datename(weekday, date) not in ('Saturday', 'Sunday')
order by date;
注意:这是假设采用英语设置,因此datename()
逻辑有效。
一种没有子查询的替代方法;
select v.dte, count(*) as cnt
from inflow i cross apply
(values (case when datename(weekday, i.date) = 'Saturday'
then dateadd(day, 2, i.date)
when datename(weekday, i.date) = 'Sunday'
then dateadd(day, 1, 9.date)
else i.date
end)
) v.dte
where i.date >= dateadd(year, -2, getdate())
group by v.dte
order by date;
答案 1 :(得分:1)
您要声明性能,但是如果不了解整个情况,很难理解如何优化查询。
虽然我一直在努力,但我注意到Gordon Linoff的回答,但是我也会继续编写我的版本,我们都遵循相同的路径,但得出的答案略有不同。
WITH DateData (date, datetoapply)
AS
(
SELECT
[date],
CASE DATEPART(w, [date])
WHEN 5 THEN DATEADD(d, 2, [date])
WHEN 6 THEN DATEADD(d, 1, [date])
ELSE date
END as 'datetoapply'
FROM inflow
WHERE [date] >= dateadd(year, -2, getdate())
)
SELECT datetoapply, count(*)
FROM DateData
GROUP BY datetoapply
ORDER BY datetoapply
虽然我无法使Gordon的查询正常工作,但我可以确认“ DATEPART(w,[date])”的性能要优于“ DATENAME(weekday,[date])”,如果在上面的查询中将其替换了,根据在Azure中填充有1万行的表,将服务器处理时间从87ms增加到181ms。