Sql server 谢谢@Nizam的回答。关于查询性能,您能说些什么呢?因为它在存储过程中会被调用数千次,并且每次更新时更新的表大约有15000行(它将是一个临时表)。我不太擅长阅读执行计划。谢谢@Nizam的回答。关于查询性能,您能说些什么呢?因为它在存储过程中会被调用数
Sql server 谢谢@Nizam的回答。关于查询性能,您能说些什么呢?因为它在存储过程中会被调用数千次,并且每次更新时更新的表大约有15000行(它将是一个临时表)。我不太擅长阅读执行计划。谢谢@Nizam的回答。关于查询性能,您能说些什么呢?因为它在存储过程中会被调用数,sql-server,cursor,row,Sql Server,Cursor,Row,谢谢@Nizam的回答。关于查询性能,您能说些什么呢?因为它在存储过程中会被调用数千次,并且每次更新时更新的表大约有15000行(它将是一个临时表)。我不太擅长阅读执行计划。谢谢@Nizam的回答。关于查询性能,您能说些什么呢?因为它在存储过程中会被调用数千次,并且每次更新时更新的表大约有15000行(它将是一个临时表)。我不太擅长阅读执行计划。 Date Cnt Val Cumulative IsLastDate ..........................
谢谢@Nizam的回答。关于查询性能,您能说些什么呢?因为它在存储过程中会被调用数千次,并且每次更新时更新的表大约有15000行(它将是一个临时表)。我不太擅长阅读执行计划。谢谢@Nizam的回答。关于查询性能,您能说些什么呢?因为它在存储过程中会被调用数千次,并且每次更新时更新的表大约有15000行(它将是一个临时表)。我不太擅长阅读执行计划。
Date Cnt Val Cumulative IsLastDate
................................................
2014-01-01 1 5 0 0
2014-01-02 1 100 0 0
2014-01-03 1 300 0 0
2014-01-04 1 300 800 1
2014-01-05 1 10 0 0
2014-01-06 1 50 0 0
2014-01-07 1 50 0 0
2014-01-08 1 150 500 1
2014-01-01 2 5 0 0
2014-01-02 2 20 0 0
2014-01-03 2 50 0 0
2014-01-04 2 100 300 1
2014-01-05 2 5 0 0
2014-01-06 2 20 0 0
2014-01-07 2 5 0 0
2014-01-08 2 10 100 1
Date Cnt Val Cumulative IsLastDate
................................................
2014-01-01 1 5 100 0
2014-01-02 1 100 200 0
2014-01-03 1 300 500 0
2014-01-04 1 300 800 1
2014-01-05 1 10 250 0
2014-01-06 1 50 300 0
2014-01-07 1 50 350 0
2014-01-08 1 150 500 1
2014-01-01 2 5 130 0
2014-01-02 2 20 150 0
2014-01-03 2 50 200 0
2014-01-04 2 100 300 1
2014-01-05 2 5 65 0
2014-01-06 2 20 85 0
2014-01-07 2 5 90 0
2014-01-08 2 10 100 1
UPDATE T
SET T.Cumulative = TT.Cumulative - TT.Val
FROM T INNER JOIN T TT ON
TT.[Date] = DATEADD(DAY,1,T.[Date]) AND TT.Cnt = T.Cnt AND T.IsLastDate <> 1
UPDATE YourTable
SET Cumulative = z.NewCumulative
FROM (
SELECT *,
SUM(Cumulative - val) OVER (PARTITION BY GroupPartition ORDER BY Date DESC)AS NewCumulative
FROM (
SELECT *,
SUM(CAST(IsLastDate AS Int)) OVER (ORDER BY Date DESC) GroupPartition
FROM YourTable
)Z
)Z
WHERE YourTable.Date = Z.Date
SUM(CAST(IsLastDate AS Int)) OVER (ORDER BY Date DESC) GroupPartition
SUM(Cumulative - val) OVER (PARTITION BY GroupPartition ORDER BY Date DESC)AS NewCumulative
WITH TBL AS (
SELECT T.*,
CASE WHEN
ROW_NUMBER() OVER (PARTITION BY T.CNT, LAST_DATE ORDER BY T.DATE) =1
THEN 0
ELSE T.VAL
END VAL_ADJ,
LAST_DATE
FROM T
CROSS APPLY (
select MAX(TE.DATE)
FROM T TE
WHERE TE.[Date] < T.[Date]
AND TE.Cnt = T.Cnt
AND TE.IsLastDate = 1
) D(LAST_DATE)
), RESULT AS (
SELECT
A.DATE,
A.CNT,
A.VAL,
SUM(B.VAL_ADJ) + TOTAL_FULL - TOTAL CUMULATIVE,
A.ISLASTDATE
FROM TBL A
CROSS APPLY (
select SUM(VAL_ADJ)
FROM TBL
WHERE ISNULL(LAST_DATE,0) = ISNULL(A.LAST_DATE,0) AND CNT = A.CNT
GROUP BY CNT, LAST_DATE
) N(TOTAL)
CROSS APPLY (
select MAX(CUMULATIVE)
FROM TBL
WHERE ISNULL(LAST_DATE,0) = ISNULL(A.LAST_DATE,0) AND CNT = A.CNT
GROUP BY CNT, LAST_DATE
) L(TOTAL_FULL)
LEFT JOIN TBL B
ON A.DATE >= B.DATE
AND A.CNT = B.CNT
AND ISNULL(A.LAST_DATE,0) = ISNULL(B.LAST_DATE,0)
GROUP BY A.DATE, A.CNT, A.VAL, A.ISLASTDATE, A.LAST_DATE, N.TOTAL, TOTAL_FULL
)
UPDATE T
SET CUMULATIVE = B.CUMULATIVE
FROM T A
INNER JOIN RESULT B
ON A.CNT = B.CNT
AND A.DATE = B.DATE
SELECT * FROM T
UPDATE T
SET CUMULATIVE = NewCumulative
FROM T
INNER JOIN (
SELECT *,
SUM(Z.Cumulative - case when linha = 1 then 0 else VAL_ANT end) OVER (PARTITION BY GroupPartition ORDER BY Z.Date DESC) AS NewCumulative
FROM (
SELECT Z.*, ROW_NUMBER() OVER(PARTITION BY GroupPartition ORDER BY Z.DATE DESC) LINHA, IsNull(T0.VAL,0) VAL_ANT
FROM (
SELECT *,
SUM(CAST(IsLastDate AS Int)) OVER (ORDER BY CNT, Date DESC) GroupPartition
FROM T
)Z
LEFT JOIN T T0
on T0.DATE = DATEADD(DAY,1,Z.DATE)
and T0.CNT = Z.CNT
) Z
) Z
ON T.Date = Z.Date AND T.CNT = Z.CNT
SELECT *
FROM T
ORDER BY CNT, DATE
SELECT M.[Date],M.Cnt,M.Val,
Cumulative =
CASE (M.IsLastDate) WHEN 1 THEN M.Cumulative
ELSE ((SELECT TOP(1) Cumulative FROM T WHERE [Date] > M.[Date] AND Cnt = M.Cnt
AND IsLastDate = 1)
-
(SELECT SUM(Val) FROM T B WHERE B.[Date] > M.[Date]
AND M.Cnt = B.Cnt
AND B.[Date] <= (SELECT TOP(1) [Date] FROM T WHERE [Date] > M.[Date]
AND Cnt = M.Cnt AND IsLastDate = 1))
)
END,
M.IsLastDate
FROM T M
ORDER BY CNT,[Date] ,IsLastDate%1 --Just for viewing in an ordered way