Sql 将周末计数转为周一计数
我有这样一个问题:Sql 将周末计数转为周一计数,sql,sql-server,Sql,Sql Server,我有这样一个问题: select date, count(*) from inflow where date >= dateadd(year, -2, getdate()) group by date order by date 我需要排除周六和周日的日期,而是将它们的计数添加到下一个周一。最好的方法是什么?我是否需要排除周六、周日和周一,然后将它们添加到另一个查询的联接中?上面的查询是一个简化版本,这是一个相对较大的查询,所以我需要记住效率 嗯,这是一种蛮力的方法: select d
select date, count(*)
from inflow
where date >= dateadd(year, -2, getdate())
group by date
order by date
我需要排除周六和周日的日期,而是将它们的计数添加到下一个周一。最好的方法是什么?我是否需要排除周六、周日和周一,然后将它们添加到另一个查询的联接中?上面的查询是一个简化版本,这是一个相对较大的查询,所以我需要记住效率 嗯,这是一种蛮力的方法:
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;
您需要声明性能,但是在不了解全局的情况下,很难理解如何优化查询 当我一直在研究这个问题时,我注意到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])”要好得多,如果在上面的查询中替换“DATENAME(weekday,[date]),则基于Azure中填充了10k行的表,服务器处理时间将从87毫秒增加到181毫秒 一个样本数据和期望的结果将在这里有所帮助。