我想从表中获取一周的项目数,我使用了以下查询:
SELECT
count(*) As Total
from MyTable
WHERE convert(date,DateCreated)>='08/17/2015'
AND convert(date,DateCreated)<='08/23/2015'
我得到的结果是(这是正确的):
Total
1149
现在我尝试重写查询以使其在一段时间内每周返回结果,并且我注意到计数未正确显示。 作为示例,我在同一时间段内使用了以下查询:
SELECT
count(*) AS Total,
DATEPART(wk, DateCreated) AS WeekNumber,
CAST(dateadd(ww, datediff(ww, 0, DateCreated), 0) AS date) as WeekStartDate,
CAST(dateadd(ww, datediff(ww, 0, DateCreated), 6) AS date) as WeekEndDate
FROM MyTable
WHERE convert(date,DateCreated) >= '08/17/2015'
and convert(date,DateCreated) <= '08/23/2015'
GROUP BY DATEPART(wk, DateCreated), CAST(dateadd(ww, datediff(ww, 0, DateCreated), 0) AS date), CAST(dateadd(ww, datediff(ww, 0, DateCreated), 6) AS date)
ORDER BY DATEPART(wk, DateCreated)
SUM
行正在返回正确的计数,但由于我的日期选择(从'08/17/2015'
到'08/23/2015'
)仅代表一周,因此预计它将只作为一行,但结果如下所示为2周
Total WeekNumber WeekStartDate WeekEndDate
1078 34 2015-08-17 2015-08-23
71 35 2015-08-24 2015-08-30
此行为的任何已知原因。是因为我使用的周计算逻辑吗?或者其他一些已知问题。
答案 0 :(得分:3)
您正在按DATEPART(wk...
分组
这使用您服务器的DATEFIRST
设置。它与计算WeekStartDate和WeekEndDate的方式不同,因此它将提供与您预期不同的WeekNumber,除非您的DATEFIRST
值设置为重合。
2015年,8月17日是星期一,8月23日是星期天。你有DATEFIRST Set to Monday吗?默认为星期日。
参见&#34; Week和DatePart参数&#34; MS Documentation。
的部分编辑:This answer根据您当前的DATEFIRST
值提供一些详细解释和提示,以获取一周的第一天。
答案 1 :(得分:1)
由于Tab最终没有提供可行的解决方案,因此这里有一个:
set datefirst 1;
select
count(*) as Total
, datepart(wk, DateCreated) as WeekNumber
, convert(date,dateadd(week,datediff(day,0,DateCreated )/7,0)) as WeekStartDate
, convert(date,dateadd(week,datediff(day,0,DateCreated )/7,6)) as WeekEndDate
from MyTable
where convert(date,DateCreated) >= '20150817' --'08/17/2015'
and convert(date,DateCreated) <= '20150823' --'08/23/2015'
group by
datepart(wk, DateCreated)
, convert(date,dateadd(week,datediff(day,0,DateCreated )/7,0))
, convert(date,dateadd(week,datediff(day,0,DateCreated )/7,6))
order by datepart(wk, DateCreated)
简单的日历示例:
declare @FromDate date = '20150817';
declare @ThruDate date = '20150831';
;with cal as (
select top (1+datediff(day, @FromDate, @ThruDate))
DateValue = convert(date,dateadd(day,row_number() over (order by (select 1))-1,@FromDate))
from [master]..spt_values v
order by DateValue
)
select
[Date] = convert(char(10),DateValue,120)
, weekday = datename(WeekDay,DateValue)
, WeekMonday = convert(date,dateadd(week,datediff(day,0,datevalue )/7,0))
, WeekSunday = convert(date,dateadd(week,datediff(day,0,datevalue )/7,6))
from cal
rextester演示:http://rextester.com/TYJ50600
返回:
+------------+-----------+------------+------------+
| Date | weekday | WeekMonday | WeekSunday |
+------------+-----------+------------+------------+
| 2015-08-17 | Monday | 2015-08-17 | 2015-08-23 |
| 2015-08-18 | Tuesday | 2015-08-17 | 2015-08-23 |
| 2015-08-19 | Wednesday | 2015-08-17 | 2015-08-23 |
| 2015-08-20 | Thursday | 2015-08-17 | 2015-08-23 |
| 2015-08-21 | Friday | 2015-08-17 | 2015-08-23 |
| 2015-08-22 | Saturday | 2015-08-17 | 2015-08-23 |
| 2015-08-23 | Sunday | 2015-08-17 | 2015-08-23 |
| 2015-08-24 | Monday | 2015-08-24 | 2015-08-30 |
| 2015-08-25 | Tuesday | 2015-08-24 | 2015-08-30 |
| 2015-08-26 | Wednesday | 2015-08-24 | 2015-08-30 |
| 2015-08-27 | Thursday | 2015-08-24 | 2015-08-30 |
| 2015-08-28 | Friday | 2015-08-24 | 2015-08-30 |
| 2015-08-29 | Saturday | 2015-08-24 | 2015-08-30 |
| 2015-08-30 | Sunday | 2015-08-24 | 2015-08-30 |
| 2015-08-31 | Monday | 2015-08-31 | 2015-09-06 |
+------------+-----------+------------+------------+
答案 2 :(得分:0)
您应该使用iso_week
作为日期部分,请看:
select
datepart(wk,'20150817'),
datepart(wk,'20150823'),
datepart(iso_week,'20150817'),
datepart(iso_week,'20150823')