TSQL Having 子句在条件下未按预期执行
TSQL Having clause not performing as expected with condition
DECLARE @ComparisonMonth DATE
SET @ComparsionMonth '09-01-2018'
SELECT
Date, Sales, CustomerID
FROM
Database1 t1
WHERE
Date >= CASE
WHEN (SELECT MAX(Date)
FROM Database1 t2
INNER JOIN ON t1.PlayerID = t2.PlayerID) >= DATEADD(month, -4, @ComparisonMonth)
AND (SELECT MAX(Date)
FROM Database1 t2
INNER JOIN ON t1.PlayerID = t2.PlayerID) < DATEADD(month, -1, @ComparsionMonth)
THEN DATEADD(month, -4, @ComparisonMonth)
WHEN (SELECT MAX(Date)
FROM Database1 t2
INNER JOIN ON t1.PlayerID = t2.PlayerID) >= DATEADD(month, -7, @ComparisonMonth)
AND (SELECT MAX(Date)
FROM Database1 t2
INNER JOIN ON t1.PlayerID = t2.PlayerID) < DATEADD(month, -4, @ComparsionMonth)
THEN DATEADD(month, -7, @ComparisonMonth)
END
AND Date < CASE
WHEN (Select MAX(Date) from Database1 t2 INNER JOIN on t1.PlayerID=t2.PlayerID) >= DATEADD(month, -4, @ComparisonMonth)
AND (Select MAX(Date) from Database1 t2 INNER JOIN on t1.PlayerID=t2.PlayerID) < DATEADD(month, -1, @ComparsionMonth)
THEN DATEADD(month, -1, @ComparisonMonth)
WHEN (Select MAX(Date) from Database1 t2 INNER JOIN on t1.PlayerID=t2.PlayerID) >= DATEADD(month, -7, @ComparisonMonth)
AND (Select MAX(Date) from Database1 t2 INNER JOIN on t1.PlayerID=t2.PlayerID) < DATEADD(month, -4, @ComparsionMonth)
THEN DATEADD(month, -4, @ComparisonMonth)
END
GROUP BY
CustomerID, Date
基本上,我只想根据客户上次购买商品的时间显示特定时期的价值。例如,如果客户在过去 3 个月内最后购买了一件商品,我想获取他们过去 3 个月的所有交易。相反,我正在为 3 个月前最后一次来的客户获取 6 个月的交易。
非常感谢您的帮助,如果您需要任何说明,请告诉我。
我的建议是停止尝试一次实现所有目标。将您的查询拆分为:
1 找到您需要的客户。非常简单的查询和精确的过滤条件:
DECLARE @Customers TABLE (CustomerID INT NOT NULL PRIMARY KEY, LastPurchase DATE, FirstTran DATE)
INSERT INTO @Customers(CustomerID, LastPurchase, FirstTran)
SELECT
CustomerID, MAX(Date), DATEADD(MM, -3, MAX(Date))
FROM Database1 d
WHERE d.date >= @ReportDate
GROUP BY CustomerID
2 获取他们的交易。现在您再次拥有良好的过滤器(连接谓词)- CustomerID。帮助服务器过滤大 table - 从收集的数据中找到绝对最小的日期。
DECLARE @MinDate DATE
SELECT @MinDate = MIN(FirstTran)
FROM @Customers
SELECT d.*
FROM Database1 d
INNER JOIN @Customers c
on c.CustomerID = d.CustomerID
WHERE d.Date >= c.FirstTran
AND d.Date >= @MinDate
测试你的解决方案,如果你想出一些微小的单步解决方案 - 按照你的意愿重构这段代码。
DECLARE @ComparisonMonth DATE
SET @ComparsionMonth '09-01-2018'
SELECT
Date, Sales, CustomerID
FROM
Database1 t1
WHERE
Date >= CASE
WHEN (SELECT MAX(Date)
FROM Database1 t2
INNER JOIN ON t1.PlayerID = t2.PlayerID) >= DATEADD(month, -4, @ComparisonMonth)
AND (SELECT MAX(Date)
FROM Database1 t2
INNER JOIN ON t1.PlayerID = t2.PlayerID) < DATEADD(month, -1, @ComparsionMonth)
THEN DATEADD(month, -4, @ComparisonMonth)
WHEN (SELECT MAX(Date)
FROM Database1 t2
INNER JOIN ON t1.PlayerID = t2.PlayerID) >= DATEADD(month, -7, @ComparisonMonth)
AND (SELECT MAX(Date)
FROM Database1 t2
INNER JOIN ON t1.PlayerID = t2.PlayerID) < DATEADD(month, -4, @ComparsionMonth)
THEN DATEADD(month, -7, @ComparisonMonth)
END
AND Date < CASE
WHEN (Select MAX(Date) from Database1 t2 INNER JOIN on t1.PlayerID=t2.PlayerID) >= DATEADD(month, -4, @ComparisonMonth)
AND (Select MAX(Date) from Database1 t2 INNER JOIN on t1.PlayerID=t2.PlayerID) < DATEADD(month, -1, @ComparsionMonth)
THEN DATEADD(month, -1, @ComparisonMonth)
WHEN (Select MAX(Date) from Database1 t2 INNER JOIN on t1.PlayerID=t2.PlayerID) >= DATEADD(month, -7, @ComparisonMonth)
AND (Select MAX(Date) from Database1 t2 INNER JOIN on t1.PlayerID=t2.PlayerID) < DATEADD(month, -4, @ComparsionMonth)
THEN DATEADD(month, -4, @ComparisonMonth)
END
GROUP BY
CustomerID, Date
基本上,我只想根据客户上次购买商品的时间显示特定时期的价值。例如,如果客户在过去 3 个月内最后购买了一件商品,我想获取他们过去 3 个月的所有交易。相反,我正在为 3 个月前最后一次来的客户获取 6 个月的交易。
非常感谢您的帮助,如果您需要任何说明,请告诉我。
我的建议是停止尝试一次实现所有目标。将您的查询拆分为:
1 找到您需要的客户。非常简单的查询和精确的过滤条件:
DECLARE @Customers TABLE (CustomerID INT NOT NULL PRIMARY KEY, LastPurchase DATE, FirstTran DATE)
INSERT INTO @Customers(CustomerID, LastPurchase, FirstTran)
SELECT
CustomerID, MAX(Date), DATEADD(MM, -3, MAX(Date))
FROM Database1 d
WHERE d.date >= @ReportDate
GROUP BY CustomerID
2 获取他们的交易。现在您再次拥有良好的过滤器(连接谓词)- CustomerID。帮助服务器过滤大 table - 从收集的数据中找到绝对最小的日期。
DECLARE @MinDate DATE
SELECT @MinDate = MIN(FirstTran)
FROM @Customers
SELECT d.*
FROM Database1 d
INNER JOIN @Customers c
on c.CustomerID = d.CustomerID
WHERE d.Date >= c.FirstTran
AND d.Date >= @MinDate
测试你的解决方案,如果你想出一些微小的单步解决方案 - 按照你的意愿重构这段代码。