问题描述
我想获得去年当月最畅销的产品。
例如今天的月份是 2021 年 5 月,所以我想获取 2020 年 5 月最畅销的产品,如果月份更改为 6 月,它会自动将 @Date1
更改为 6 月 1 并将 @Date2
更改为 6 月30.
这是我使用 DateTimePicker
获得最畅销商品的查询。
SELECT SUM
( Sales.Qty ) AS Qty_Sold,Sales.ProductID,Products.ProductDesc,Sales.Price,SUM ( Sales.Total ) AS Total_Sales FROM
dbo.Sales
INNER JOIN dbo.Products ON Sales.ProductID = Products.ProductID WHERE
Sales.SalesDate BETWEEN @Date1 AND @Date2 GROUP BY
Sales.ProductID,Sales.Price
但是如何在没有 DateTimePicker
的情况下做到这一点。
解决方法
你的意思是基于 SQLServer 的时钟?
BETWEEN
DATEADD(day,1,EOMONTH(GetUtcDate(),-13))) AND EOMONTH(GetUtcDate(),-12)
EOMONTH 是一个方便的函数,可将输入日期转换为该月最后一天的日期。 GetUtcDate() 获取 sqlserver 时钟的当前时间(以 UTC 为单位)
这意味着我们可以取今天(2日)sqlserver的时钟日期,用-13个月滚动使其成为去年的4月30日,再加一天成为5月1日
与结束日期类似,我们可以将当前日期设为 5 月底,使用 -12 个月滚动到去年 5 月底
请注意,如果您的销售表中的日期也有时间,您应该改为:
WHERE
Sales.SalesDate >= DATEADD(day,-13)) AND
Sales.SalesDate < DATEADD(day,-12))
因为时间代表一天的“十进制”部分(如果午夜 00:00 类似于 1.0,则意味着 23:59:59.999999 类似于 1.999999..)如果您使用 BETWEEN
那么您会错过最后一天午夜后售出的每件产品。相反,使用 >=
和 <
,“小于”是“小于第二天午夜”,这将捕获甚至在 23:59:59.999999 销售的产品
我们应该这样做,而不是通过截断时间来转换表数据;始终尽量避免转换或操作表数据以使其与参数匹配,因为这通常会对性能产生重大影响
,您可以在 postgreSQL 中使用 date_trunc()。
我们可以按如下方式进行内连接
INNER JOIN dbo.Products
ON Sales.ProductID = Products.ProductID
WHERE
date_trunc('month',current_date) = date_trunc('month',Sales.SalesDate) + interval '1 year'