尝试在一周内按天获取订单时生成SQL查询时出错



我有一个ASP。NET核心应用程序,通过控制器端点,我将@by@period字符串值传递给SQL查询。

  • @by取以下值之一:天、周
  • @period取以下值之一:周、月、年

如果@period是月或年,那么@by是一周,否则就是一天。

@period是一个月或一年时,我有以下工作查询:

SELECT
l.region_id AS region_id,
'Region ' + r.region_desc AS region_name,
MIN(DATEADD(D, -(DATEPART(WEEKDAY, s.pos_date) - 1), s.pos_date)) AS date_pos,
CONVERT(VARCHAR(20), MIN(DATEADD(D, -(DATEPART(WEEKDAY, s.pos_date) - 1), s.pos_date)), 107) AS display_date_pos
FROM 
incent_summary s 
INNER JOIN 
location l ON s.store_num = l.store_num
INNER JOIN
region r ON l.region_id = r.region_id
WHERE 
s.pos_date >= DATEADD(day, @period , CONVERT(date, GETDATE()))
AND s.pos_date <= GETDATE()
GROUP BY 
DATEPART (@by, s.pos_date), 
l.region_id, r.region_desc
ORDER BY 
DATEPART (@by, pos_date),
l.region_id, r.region_desc

问题是当@period是一周,@by是一天,并且语句

MIN(DATEADD(D, -(DATEPART(WEEKDAY, s.pos_date) - 1), s.pos_date)) AS date_pos

返回所有7天的同一天。

@period = year@by = week:时的样本输出

region_id   region_name  date_pos                   display_date_pos
---------------------------------------------------------------------
34          Region 43    2019-12-29 00:00:00.000    Dec 29, 2019
50          Region 22    2019-12-29 00:00:00.000    Dec 29, 2019
34          Region 43    2020-01-05 00:00:00.000    Jan 05, 2020
50          Region 22    2020-01-05 00:00:00.000    Jan 05, 2020
34          Region 43    2020-01-12 00:00:00.000    Jan 12, 2020
50          Region 22    2020-01-12 00:00:00.000    Jan 12, 2020
34          Region 43    2020-01-19 00:00:00.000    Jan 19, 2020
50          Region 22    2020-01-19 00:00:00.000    Jan 19, 2020
34          Region 43    2020-01-26 00:00:00.000    Jan 26, 2020
50          Region 22    2020-01-26 00:00:00.000    Jan 26, 2020

@period = week and @by = day:时的样本输出

region_id   region_name  date_pos                   display_date_pos
--------------------------------------------------------------------
34          Region 43    2020-07-12 00:00:00.000    Jul 12, 2020
50          Region 22    2020-07-12 00:00:00.000    Jul 12, 2020
34          Region 43    2020-07-12 00:00:00.000    Jul 12, 2020
50          Region 22    2020-07-12 00:00:00.000    Jul 12, 2020
34          Region 43    2020-07-19 00:00:00.000    Jul 19, 2020
50          Region 22    2020-07-19 00:00:00.000    Jul 19, 2020
34          Region 43    2020-07-19 00:00:00.000    Jul 19, 2020
50          Region 22    2020-07-19 00:00:00.000    Jul 19, 2020
34          Region 43    2020-07-19 00:00:00.000    Jul 19, 2020
50          Region 22    2020-07-19 00:00:00.000    Jul 19, 2020

我该怎么解决这个问题?

SELECT
DATEADD(D, -(DATEPART(WEEKDAY, s.pos_date) - 1), s.pos_date)

将总是在一周的第一天返回,因为逻辑是:;从我的日期中减去周日之后的天数,再加1;

Sunday: 1 - 1 + 1 = 1 = Sunday 
Monday: 2 - 2 + 1 = 1 = Sunday
.
.
.
Saturday: 7 - 7 + 1 = Sunday

当你想要一年/一个月/任何时候的第一个星期天时,这很好。但是每个星期的第一个星期天总是。。。星期日但在这种情况下,如果@period是周,你真的只需要服用MIN(s.pos_date)

可能有一些疯狂的方法可以在一个使用四元数或其他超数学的语句中实现这一点,但最简单的方法是只使用case语句:

MIN
(
CASE
WHEN '@by' = 'day' THEN s.pos_date
ELSE DATEADD(D, -(DATEPART(WEEKDAY, s.pos_date) - 1), s.pos_date)
END
)

我不是C#程序员,所以我不能告诉你确保字符串DAY作为"DAY"传递给查询的确切方法,但我相信你可以处理这部分。

同样重要日期部分";"天";是一个月中的某一天,所以如果您的跨度可能大于一个月(但不到一年(,请使用dayofyear

最新更新