sql-server - SQL - 按周分组在特定工作日开始而不涉及两个事务?
问题描述
我正在编写一个查询,返回过去 10 周周五至周四的行总和。
它使用 group by 来显示每周的总和:
WITH Vars (Friday) -- get current week Fridays Date
AS (
SELECT CAST(DATEADD(DAY,(13 - (@@DATEFIRST + DATEPART(WEEKDAY,GETDATE())))%7,GETDATE()) AS DATE) As 'Friday'
)
SELECT datepart(week, DateField) AS WeekNum, COUNT(*) AS Counts
FROM Table
WHERE DateField >= DATEADD(week,-9, (SELECT Friday from Vars))
GROUP BY datepart(week, DateField)
ORDER BY WeekNum DESC
问题是每周从星期一开始,因此 Group By 不会按照我想要的方式对日期进行分组。我希望将一周定义为周五至周四。
一种解决方法是使用 DATEFIRST。例如:
SET DATEFIRST = 5; --set beginning of each week to Friday
WITH Vars (Friday) -- get current week Fridays Date
... rest of query
但是,由于我正在编写此查询的界面的限制,我不能运行两个单独的语句。它必须是一个不带分号的查询。
我怎样才能做到这一点?
解决方案
这应该这样做。首先在 9 周前的 StartingFriday 进行一次预计算,而不是对每一行都进行预计算。然后计算 dfYear 和 dfWeek 给他们 alias-es,他们的 DateField 在开始星期五之后。最后,Count/GroupBy/OrderBy。
Declare @StartingFriday as date =
DATEADD(week,-9, (DATEADD(day, - ((Datepart(WEEKDAY,GETDATE()) +1) % 7) , GETDATE())) ) ;
SELECT dfYear, dfWeek, COUNT(*) AS Counts
FROM
(Select -- compute these here, and use alias in Select, GroupBy, OrderBy
(Datepart(Year,(DATEADD(day, - ((Datepart(WEEKDAY,DateField) +1) % 7) , DateField)) ) )as dfYear
,(Datepart(Week,(DATEADD(day, - ((Datepart(WEEKDAY,DateField) +1) % 7) , DateField)) ) )as dfWeek
From Table
WHERE @StartingFriday <= DateField
) as aa
group by dfYear, dfWeek
order by dfYear desc, dfWeek desc
-- we want the weeknum of the (Friday on or before the DateField)
-- the % (percent sign) is the math MODULO operator.
-- used to get back to the nearest Friday,
-- day= Fri Sat Sun Mon Tue Wed Thu
-- weekday= 6 7 1 2 3 4 5
-- plus 1 = 7 8 2 3 4 5 6
-- Modulo7= 0 1 2 3 4 5 6
-- which are the days to subtract from DateField
-- to get to its Friday start of its week.
我对此做了一些测试
declare @dt as date = '8/17/18';
select ((DATEPART(WEEKDAY,@dt) +1) % 7) as wd
,(DATEADD(day, - ((Datepart(WEEKDAY,@dt) +1) % 7) , @dt)) as Fri
,(Datepart(Week,(DATEADD(day, - ((Datepart(WEEKDAY,@dt) +1) % 7) , @dt)) ) )as wk
,DATEADD(week,-9, (DATEADD(day, - ((Datepart(WEEKDAY,@dt) +1) % 7) , @dt)) ) as StartingFriday
推荐阅读
- python - pandas DataFrame 根据不同列在布尔掩码上设置值
- android - 配置“:app:api”包含在依赖项解析中后无法更改依赖项
- google-apps-marketplace - 作为之前发布列表的开发者,我如何从 G Suite 市场中删除列表?
- asp.net-mvc - 未处理的 Promise 拒绝:未设置基本 href。请为 APP_BASE_HREF 令牌提供值或向文档添加基本元素
- c# - 如何使用 NEST (Elasticsearch) UpdateByQuery 更新多个字段?
- sql - SQL 连接表以聚合 ID 列表?
- scala - 合并可能为空的数据框列表
- xml - 如何使用 PowerShell 替换其字符串中包含反斜杠 ( \ ) 的文件内容?
- jquery - 单击时切换下拉菜单并隐藏所有其他下拉菜单
- python - 为什么我的 equal 方法总是返回 false?