Using windowed functions (SUM/ROW_NUMBER
so it will work with SQL Server 2008
):
WITH cte AS
(
SELECT *, s = SUM(TP_DAYS) OVER(PARTITION BY EMP_ID ORDER BY ROW_NUM)
FROM #tab
), cte2 AS
(
SELECT *,
tp_days_recalculated = ROW_NUMBER() OVER (PARTITION BY EMP_ID, s ORDER BY ROW_NUM)
FROM cte
)
UPDATE cte2
SET TP_DAYS = tp_days_recalculated;
SELECT *
FROM #tab;
LiveDemo
Output:
╔═════════╦════════╦══════════╦═════════╗
║ ROW_NUM ║ EMP_ID ║ DATE_KEY ║ TP_DAYS ║
╠═════════╬════════╬══════════╬═════════╣
║ 1 ║ U12345 ║ 20131003 ║ 1 ║
║ 2 ║ U12345 ║ 20131004 ║ 2 ║
║ 3 ║ U12345 ║ 20131005 ║ 3 ║
║ 4 ║ U12345 ║ 20131006 ║ 4 ║
║ 5 ║ U12345 ║ 20150627 ║ 1 ║
║ 6 ║ U12345 ║ 20150628 ║ 2 ║
║ 1 ║ U54321 ║ 20131003 ║ 1 ║
║ 2 ║ U54321 ║ 20131004 ║ 2 ║
║ 3 ║ U54321 ║ 20131005 ║ 3 ║
║ 4 ║ U54321 ║ 20131006 ║ 4 ║
╚═════════╩════════╩══════════╩═════════╝
#Addendum
Original OP question and sample data are very clear that tp_days
indicators are 0
and 1
not any other values.
Especially for Atheer Mostafa:
check this example as a proof: https://data.stackexchange.com/stackoverflow/query/edit/423186
This should be new question, but I will handle that case:
;WITH cte AS
(
SELECT *
,rn = s + ROW_NUMBER() OVER(PARTITION BY EMP_ID, s ORDER BY ROW_NUM) -1
,rnk = DENSE_RANK() OVER(PARTITION BY EMP_ID ORDER BY s)
FROM (SELECT *, s = SUM(tp_days) OVER(PARTITION BY EMP_ID ORDER BY ROW_NUM)
FROM #tab) AS sub
), cte2 AS
(
SELECT c1.*,
tp_days_recalculated = c1.rn - (SELECT COALESCE(MAX(c2.s),0)
FROM cte c2
WHERE c1.emp_id = c2.emp_id
AND c2.rnk = c1.rnk-1)
FROM cte c1
)
UPDATE cte2
SET tp_days = tp_days_recalculated;
LiveDemo2
Output:
╔═════════╦════════╦══════════╦═════════╗
║ row_num ║ emp_id ║ date_key ║ tp_days ║
╠═════════╬════════╬══════════╬═════════╣
║ 1 ║ U12345 ║ 20131003 ║ 2 ║
║ 2 ║ U12345 ║ 20131004 ║ 3 ║
║ 3 ║ U12345 ║ 20131005 ║ 4 ║
║ 4 ║ U12345 ║ 20131006 ║ 3 ║
║ 5 ║ U12345 ║ 20150627 ║ 4 ║
║ 6 ║ U12345 ║ 20150628 ║ 5 ║
║ 1 ║ U54321 ║ 20131003 ║ 2 ║
║ 2 ║ U54321 ║ 20131004 ║ 3 ║
║ 3 ║ U54321 ║ 20131005 ║ 1 ║
║ 4 ║ U54321 ║ 20131006 ║ 2 ║
╚═════════╩════════╩══════════╩═════════╝
it shouldn't change the values 3,4,2 to 1 .... this is the case. I don't need your solution when I have another generic answer, you don't tell me what to do ... thank you
Solution mentioned in comment is nothing more than quirky update
. Yes it will work, but may easily fail:
- First of all there is no such thing as ordered table per se
- Query optimizer may read data in any way(especially when dataset is big and parallel execution is involved). Without
ORDER BY
you cannot guarantee the stable result
- The behavior is not documented,might work today but could break in the future
Related articles:
- Robyn Page's SQL Server Cursor Workbench
- Calculate running total / running balance
- No Seatbelt - Expecting Order without ORDER BY