试一试。
首先创建 3 个公用表表达式 (CTE)。您可以将它们作为嵌套子查询来执行,但我发现 CTE 更易于阅读和管理,而且它们更易于解释。
WITH ninety_day_cte
AS
(SELECT temporders.site, temporders.number, temporders.customernumber, temporders.orderdate
FROM orders
WHERE
temporders.orderdate >= DATEADD(DAY,-ninety,GETDATE())),
ninety_day_count_cte
AS
(SELECT temporders.customernumber, COUNT(*) AS Order_Count
FROM orders
WHERE
temporders.orderdate >= DATEADD(DAY,-ninety,GETDATE())
GROUP BY
temporders.customernumber),
greater_ninety_day_cte
AS
(SELECT temporders.site, temporders.number, temporders.customernumber, temporders.orderdate,
ROW_NUMBER() OVER(PARTITION BY temporders.customernumber ORDER BY temporders.orderdate DESC) AS Row_Number
FROM orders
WHERE
temporders.orderdate < DATEADD(DAY,-ninety,GETDATE()))
第一个 CTE,ninety_day_cte 将获取过去 90 天内的所有订单 - 我们需要所有客户,我们需要所有订单。很简单,我们可以把这个放在一边。
第二个 CTE,ninety_day_count_cte 用于确定过去 90 天内每位客户的订单总数。我们需要知道这个数字来确定我们需要抓取多少超过 90 天的订单。
第三个 CTE,greater_ninety_day_cte 将获取所有超过 90 天的订单。我们添加 ROW_NUMBER() 以按订单日期对每个客户的订单进行排名 - 这将帮助我们获取过去 90 天所需的订单。
现在我们需要添加查询来获取过去 90 天的订单:
SELECT site, number, customernumber, orderdate
FROM greater_ninety_day_cte AS g
LEFT JOIN ninety_day_count AS c
ON g.customernumber = c.customernumber
WHERE
g.Row_Number <= CASE
WHEN CASE WHEN c.Order_Count IS NULL THEN 0 ELSE c.Order_Count END > 6 THEN 1
ELSE (6 - CASE WHEN c.Order_Count IS NULL THEN 0 ELSE c.Order_Count END)
END
这使用了第 2 和第 3 个 CTE。我们使用 LEFT JOIN,因此我们为只有超过 90 天的订单的客户获取数据。 WHERE 子句从第 3 个 CTE 获取 Row_Number,并将其与来自第 2 个 CTE 的 Order_Count 进行比较。 CASE 子句规定,如果 Order_Count(过去 90 天的订单数)大于 6,我们只想拉取 Row_Number >= 1,但如果 Order_Count 小于 6,那么我们想拉取差值(6 - Order_Count)。这应该会得到所有超过 90 天且符合要求的订单。
现在我们只需要获得少于 90 天的订单。这可以通过使用第一个 CTE 的 UNION ALL 语句轻松完成:
UNION ALL
SELECT site, number, customernumber, orderdate
FROM ninety_day_cte
这应该会为您提供所需的所有结果。至少 6 个订单和至少 1 个超过 90 天的订单。
这是完整的查询:
WITH ninety_day_cte
AS
(SELECT temporders.site, temporders.number, temporders.customernumber, temporders.orderdate
FROM orders
WHERE
temporders.orderdate >= DATEADD(DAY,-ninety,GETDATE())),
ninety_day_count_cte
AS
(SELECT temporders.customernumber, COUNT(*) AS Order_Count
FROM orders
WHERE
temporders.orderdate >= DATEADD(DAY,-ninety,GETDATE())
GROUP BY
temporders.customernumber),
greater_ninety_day_cte
AS
(SELECT temporders.site, temporders.number, temporders.customernumber, temporders.orderdate,
ROW_NUMBER() OVER(PARTITION BY temporders.customernumber ORDER BY temporders.orderdate DESC) AS Row_Number
FROM orders
WHERE
temporders.orderdate < DATEADD(DAY,-ninety,GETDATE()))
SELECT site, number, customernumber, orderdate
FROM greater_ninety_day_cte AS g
LEFT JOIN ninety_day_count AS c
ON g.customernumber = c.customernumber
WHERE
g.Row_Number <= CASE
WHEN CASE WHEN c.Order_Count IS NULL THEN 0 ELSE c.Order_Count END > 6 THEN 1
ELSE (6 - CASE WHEN c.Order_Count IS NULL THEN 0 ELSE c.Order_Count END)
END
UNION ALL
SELECT site, number, customernumber, orderdate
FROM ninety_day_cte