按日历周/问题分组的查询:日期扩展超过一年
Query grouped by calendar week / Issue: Date expands over more than one year
我有一个 SQL 查询,它计算两个总和的报价。该报价应按周计算。因此使用 Datepart('ww', Date, 2, 2)
来获取日历周。
此查询在 2014 年期间运行良好,但现在我遇到了问题。
用户使用日期选择器以开始日期和结束日期的形式进行选择,然后在 where 子句中仅用于 select 相关记录。
如果他们选择了过去一年的起始日期(例如 2014 年)和今年的截止日期,我的查询将显示不相关的数据,因为它不会将年份与日历周相加。
那么,如何按日历周分组并且只选择正确年份的记录。
SELECT DatePart('ww',Date,2,2) AS WEEK,
Year(Workload_Date) AS [YEAR],
(SUM(Value1)+SUM(Value2))AS [Total1],
(SUM(Value3)+SUM(Value4)) AS [Total2],
((SUM(Value1)+SUM(Value2))/(SUM(Value3)+SUM(Value4))) AS [Quote]
FROM tbl
WHERE DatePart('ww',Date,2,2) Between DatePart('ww',FromDatePickerField,2,2) And DatePart('ww',ToDatePickerField,2,2)
GROUP BY DatePart('ww',Date,2,2), Year(Date)
ORDER BY Year(Date), DatePart('ww',Date,2,2);
table 每天包含一条记录。
Date | Value1 | Value2 | Value3 | Value4 |
01.01.2014 | 4 | 3 | 2 | 3 |
02.01.2014 | 4 | 3 | 9 | 3 |
03.01.2014 | 4 | 3 | 4 | 1 |
04.01.2014 | 4 | 3 | 1 | 3 |
...
01.01.2015 | 4 | 3 | 6 | 3 |
02.01.2015 | 4 | 3 | 3 | 7 |
您可以将您的逻辑基于 Week_Ending_date
而不是周数和年份,这样您就可以每周汇总所有数据并让 SQL 处理 week/year检测逻辑。
以防万一,您的日期范围跨越 2 年,即便如此,计算仍将基于 week_ending_date 并且应该正确计算。
类似...
SELECT DATEADD(dd, 7-(DATEPART(dw, DATE)), DATE) AS WEEK_ENDING_DATE
,Year(DATEADD(dd, 7-(DATEPART(dw, DATE)), DATE)) AS [YEAR]
,(SUM(Value1) + SUM(Value2)) AS [Total1]
,(SUM(Value3) + SUM(Value4)) AS [Total2]
,((SUM(Value1) + SUM(Value2)) / (SUM(Value3) + SUM(Value4))) AS [Quote]
FROM tbl
WHERE DATEADD(dd, 7-(DATEPART(dw, DATE)), DATE) BETWEEN DATEADD(dd, 7-(DATEPART(dw, FromDatePickerField)), FromDatePickerField)
AND DATEADD(dd, 7-(DATEPART(dw, ToDatePickerField)), ToDatePickerField)
and date >= FromDatePickerField
and date <= ToDatePickerField
GROUP BY DATEADD(dd, 7-(DATEPART(dw, DATE)), DATE)
ORDER BY DATEADD(dd, 7-(DATEPART(dw, DATE)), DATE)
我看到了 2 个可能的解决方案。
1) 只要两个日期选择器的年份不同,您就会在表单上使用日期选择器时停止用户。也许是 MsgBox 或其他东西,
2) 您将 to-DatePicker 更改为 from-Year。
DECLARE @MinDate DATE = '01.11.2014'
DECLARE @tmpDate DATE = '12.02.2015'
DECLARE @MaxDate DATE = (CASE WHEN Year(@MinDate) != Year(@tmpDate) THEN Convert(DATE, '31.12.' + Convert(VARCHAR(4), Year(@MinDate))) ELSE @tmpDate END)
SELECT @MinDate, @tmpDate, @MaxDate
结果:
minDate tmpDate maxDate
01.11.2014 12.02.2015 31.12.2014
我有一个 SQL 查询,它计算两个总和的报价。该报价应按周计算。因此使用 Datepart('ww', Date, 2, 2)
来获取日历周。
此查询在 2014 年期间运行良好,但现在我遇到了问题。
用户使用日期选择器以开始日期和结束日期的形式进行选择,然后在 where 子句中仅用于 select 相关记录。
如果他们选择了过去一年的起始日期(例如 2014 年)和今年的截止日期,我的查询将显示不相关的数据,因为它不会将年份与日历周相加。
那么,如何按日历周分组并且只选择正确年份的记录。
SELECT DatePart('ww',Date,2,2) AS WEEK,
Year(Workload_Date) AS [YEAR],
(SUM(Value1)+SUM(Value2))AS [Total1],
(SUM(Value3)+SUM(Value4)) AS [Total2],
((SUM(Value1)+SUM(Value2))/(SUM(Value3)+SUM(Value4))) AS [Quote]
FROM tbl
WHERE DatePart('ww',Date,2,2) Between DatePart('ww',FromDatePickerField,2,2) And DatePart('ww',ToDatePickerField,2,2)
GROUP BY DatePart('ww',Date,2,2), Year(Date)
ORDER BY Year(Date), DatePart('ww',Date,2,2);
table 每天包含一条记录。
Date | Value1 | Value2 | Value3 | Value4 |
01.01.2014 | 4 | 3 | 2 | 3 |
02.01.2014 | 4 | 3 | 9 | 3 |
03.01.2014 | 4 | 3 | 4 | 1 |
04.01.2014 | 4 | 3 | 1 | 3 |
...
01.01.2015 | 4 | 3 | 6 | 3 |
02.01.2015 | 4 | 3 | 3 | 7 |
您可以将您的逻辑基于 Week_Ending_date
而不是周数和年份,这样您就可以每周汇总所有数据并让 SQL 处理 week/year检测逻辑。
以防万一,您的日期范围跨越 2 年,即便如此,计算仍将基于 week_ending_date 并且应该正确计算。
类似...
SELECT DATEADD(dd, 7-(DATEPART(dw, DATE)), DATE) AS WEEK_ENDING_DATE
,Year(DATEADD(dd, 7-(DATEPART(dw, DATE)), DATE)) AS [YEAR]
,(SUM(Value1) + SUM(Value2)) AS [Total1]
,(SUM(Value3) + SUM(Value4)) AS [Total2]
,((SUM(Value1) + SUM(Value2)) / (SUM(Value3) + SUM(Value4))) AS [Quote]
FROM tbl
WHERE DATEADD(dd, 7-(DATEPART(dw, DATE)), DATE) BETWEEN DATEADD(dd, 7-(DATEPART(dw, FromDatePickerField)), FromDatePickerField)
AND DATEADD(dd, 7-(DATEPART(dw, ToDatePickerField)), ToDatePickerField)
and date >= FromDatePickerField
and date <= ToDatePickerField
GROUP BY DATEADD(dd, 7-(DATEPART(dw, DATE)), DATE)
ORDER BY DATEADD(dd, 7-(DATEPART(dw, DATE)), DATE)
我看到了 2 个可能的解决方案。
1) 只要两个日期选择器的年份不同,您就会在表单上使用日期选择器时停止用户。也许是 MsgBox 或其他东西,
2) 您将 to-DatePicker 更改为 from-Year。
DECLARE @MinDate DATE = '01.11.2014'
DECLARE @tmpDate DATE = '12.02.2015'
DECLARE @MaxDate DATE = (CASE WHEN Year(@MinDate) != Year(@tmpDate) THEN Convert(DATE, '31.12.' + Convert(VARCHAR(4), Year(@MinDate))) ELSE @tmpDate END)
SELECT @MinDate, @tmpDate, @MaxDate
结果:
minDate tmpDate maxDate
01.11.2014 12.02.2015 31.12.2014