使用AdventureWorks2014数据库,我想选择以下数据:对于每个客户,我希望在第一个订单的12个月内完成所有订单。我最终得到了解决方案:
WITH dates AS
(
SELECT soh.CustomerID
,MIN(soh.OrderDate) AS MinOrderDate
,DATEADD(MONTH, 12, MIN(soh.OrderDate)) as MaxOrderDate
FROM Sales.SalesOrderHeader soh
JOIN Sales.SalesOrderDetail sod ON sod.SalesOrderID=soh.SalesOrderID
GROUP BY soh.CustomerID
)
SELECT soh.CustomerID
,soh.OrderDate
,sod.ProductID
FROM Sales.SalesOrderHeader soh
JOIN Sales.SalesOrderDetail sod ON sod.SalesOrderID=soh.SalesOrderID
JOIN dates on dates.CustomerID=soh.CustomerID
WHERE soh.OrderDate BETWEEN MinOrderDate AND MaxOrderDate
ORDER BY soh.CustomerID
不确定这是否正确?我想知道是否存在更简单的解决方案?
答案 0 :(得分:1)
我认为这有点简单。
窗口函数MIN() OVER()
为您提供每个客户的第一个订单日期。然后,您只需为每个客户选择指定范围内的订单。
SELECT customerid,orderdate,productid
FROM (
SELECT
soh.*,sod.*,
MIN(soh.OrderDate) OVER(PARTITION BY soh.CustomerID) AS FirstOrderDate
FROM Sales.SalesOrderHeader soh
JOIN Sales.SalesOrderDetail sod ON sod.SalesOrderID=soh.SalesOrderID
) t
WHERE DATEDIFF(dd,firstorderdate,orderdate) <= 365
答案 1 :(得分:1)
;WITH cte AS (
SELECT
soh.*
,sod.*
,MIN(soh.OrderDate) OVER (PARTITION BY soh.CustomerId) as MinOrderDate
FROM
Sales.SalesOrderHeader soh
INNER JOIN Sales.SalesOrderDetail sod
ON soh.SalesOrderId = sod.SalesOrderId
)
SELECT *
FROM
cte
WHERE
OrderDate BETWEEN MinOrderDate AND DATEADD(year,1,MinOrderDate)
我同意VKP使用MIN()OVER的方法,但不同意他的日期比较。如果您希望它包含两个日期或下面的代码以排除上限日期,我会使用BETWEEN
。我不同意365比较的原因是闰年。
OrderDate >= MinOrderDate
AND OrderDate < DATEADD(year,1,MinOrderDate)