如何在SQL中对跨两年的最近四周(含当前周)进行排序?
解决跨年周数排序问题
问题根源
- 周数计算错误:你原本的代码中把日期转换为年月字符串后再计算ISO周数,这会导致周数统计失真(比如丢失了52周的数据),应该直接用原始日期计算周数。
- 排序逻辑错误:仅按周数字段
PerWeek排序时,跨年场景下第1周的数字(1)会比上一年的周数(52、51等)小,升序排序会把最新的周放在最后,不符合你的需求。
修正后的SQL代码
方案一:按周的实际日期排序(推荐)
通过获取每周的代表日期(如周内最大日期)来排序,确保时间顺序正确:
WITH WeeklyAttendance AS ( SELECT CONCAT(ROUND(COUNT(CASE WHEN db.PRESENT=1 THEN 1 ELSE NULL END)* 100.0 / COUNT(*), 2), 0) AS Present, DATEPART(iso_week, db.Day) AS PerWeek, -- 取该周的最后一天作为排序依据 MAX(db.Day) AS WeekEndDate FROM db.Attending WHERE db.Day >= DATEADD(WEEK, -5, GETDATE()) AND db.Day <= GETDATE() GROUP BY DATEPART(iso_week, db.Day) ) SELECT Present, PerWeek FROM WeeklyAttendance ORDER BY WeekEndDate DESC;
方案二:结合年份与周数排序
如果需要保留年份维度,可以同时按年份倒序、周数倒序排列:
SELECT CONCAT(ROUND(COUNT(CASE WHEN db.PRESENT=1 THEN 1 ELSE NULL END)* 100.0 / COUNT(*), 2), 0) AS Present, DATEPART(iso_week, db.Day) AS PerWeek FROM db.Attending WHERE db.Day >= DATEADD(WEEK, -5, GETDATE()) AND db.Day <= GETDATE() GROUP BY DATEPART(year, db.Day), DATEPART(iso_week, db.Day) ORDER BY DATEPART(year, db.Day) DESC, DATEPART(iso_week, db.Day) DESC;
效果说明
两种方案都会输出你期望的顺序:
Present PerWeek 48.93 1 28.05 52 6.55 51 71.02 50 73.33 49
内容的提问来源于stack exchange,提问作者BloodOverdrive
相关产品推荐
相关产品推荐

