这是常见问题,我希望在详细信息的末尾包含摘要列(特别是句点的最大值)。我不是假设我建议的方式是唯一的方式,因为我可以猜测或者有一个摘要行。无论如何假设以下数据集(比如ContractExpenses):
Contract | Period | Amount
---------+--------+-------
A | 201803 | 50.00
A | 201803 | 100.00
A | 201802 | 30.00
A | 201802 | 40.00
A | 201801 | 5.00
B | 201803 | 60.00
C | 201802 | 6.00
我的参数是Period
,比如201803。
我想要的结果集是:
Contract | Period | Amount | MaxAmountForThisMonth | MaxAmountForLastMonth
---------+--------+--------+-----------------------+-----------------------
A | 201803 | 50.00 | 100.00 | 40.00
A | 201803 | 100.00 | 100.00 | 40.00
B | 201303 | 60.00 | 60.00 |
然而,这似乎是一件显而易见的事情;首先考虑我使用多嵌套CTE获取我的数据集(ContractExpenses
)的事实,所以如果我必须在另一个嵌套CTE中重用它,那么我的查询已经需要时间。我知道聪明的alecs会说首先将你的数据转储到临时表中;这是一个预定义的内联表值函数,我只需要更新,你可以在存储过程中做一些你不能在函数中做的事情,所以假设只是为了幽默我这是唯一的方法。除了这一点我需要将该函数重用于另一个目的与另一个过滤条件,所以如果我必须删除该函数并使用存储过程,那么我也改变了另一个过程,我试图避免。
最简单的方法我可以考虑假设一个临时表(对于我下面的示例数据,我将只使用一个嵌套的CTE):
DECLARE @Period INT = 201803
DECLARE @LastMonth DATE, @LastPeriod INT
SELECT
@LastMonth = DATEADD(month, -1, DATEFROMPARTS(@Period / 100, @Period % 100, 1)),
@LastPeriod = YEAR(@LastMonth) * 100 + MONTH(@LastMonth);
WITH CTEContract(Contract, Period, Amount) AS
(
SELECT 'A', 201803, 50.00 UNION ALL
SELECT 'A', 201803, 100.00 UNION ALL
SELECT 'A', 201802, 30.00 UNION ALL
SELECT 'A', 201802, 40.00 UNION ALL
SELECT 'A', 201801, 5.00 UNION ALL
SELECT 'B', 201803, 60.00 UNION ALL
SELECT 'C', 201802, 6.00
)
SELECT *
INTO #ContractExpenses
FROM CTEContract;
WITH CTELastMonth AS
(
SELECT
Contract, MAX(Amount) AS MaxAmountForLastMonth
FROM
#ContractExpenses
WHERE
Period = @LastPeriod
GROUP BY
Contract
)
SELECT
t.*,
MAX(t.Amount) OVER (PARTITION BY t.Contract) AS MaxAmountForThisMonth,
l.MaxAmountForLastMonth
FROM
#ContractExpenses t
LEFT JOIN
CTELastMonth l ON t.Contract = l.Contract
WHERE
Period = @Period
DROP TABLE #ContractExpenses
所以无论如何都要在函数中使用它,即我无法选择函数中的临时表,我不能使用进一步的嵌套CTE,因为这会使我的函数时间耗尽到不可接受的水平。我确实考虑过使用LAG,但我无法弄明白。
答案 0 :(得分:0)
我找不到解决方案所以我被迫放弃了这个功能。我创建了一个视图来创建ContractExpenses并多次使用它,因此使用我在上面提供的存储过程中的解决方案,以及我需要相同数据集的其他过程的类似。