Create calculated value based on calculated value inside previous row










1















I'm trying to find a way to apply monthly percentage changes to forecast pricing. I set my problem up in excel to make it a bit more clear. I'm using SQL Server 2017.



PricingTable Sample Data



We'll say all months before 9/1/18 are historical and 9/1/18 and beyond are forecasts. I need to calculate the forecast price (shaded in yellow on the sample data) using...



Forecast Price = (Previous Row Forecast Price * Pct Change) + Previous Row Forecast Price


Just to be clear, the yellow shaded prices do not exist in my data yet. That is what I am trying to have my query calculate. Since this is monthly percentage change, each row depends on the row before and goes beyond a single ROW_NUMBER/PARTITION solution because we have to use the previous calculated price. Clearly what is an easy sequential calculation in excel is a bit more difficult here. Any idea how to create forecasted price column in SQL?










share|improve this question
























  • WHere is the first 150 coming from?

    – Salman A
    Nov 12 '18 at 19:04











  • 150 = 50% * 100 + 100. Price from 1/1/18, plus the 50% price increase.

    – BenM
    Nov 12 '18 at 19:05











  • I believe you need to solve it with recursion. LAG/SUM OVER won't help here.

    – Salman A
    Nov 13 '18 at 6:05















1















I'm trying to find a way to apply monthly percentage changes to forecast pricing. I set my problem up in excel to make it a bit more clear. I'm using SQL Server 2017.



PricingTable Sample Data



We'll say all months before 9/1/18 are historical and 9/1/18 and beyond are forecasts. I need to calculate the forecast price (shaded in yellow on the sample data) using...



Forecast Price = (Previous Row Forecast Price * Pct Change) + Previous Row Forecast Price


Just to be clear, the yellow shaded prices do not exist in my data yet. That is what I am trying to have my query calculate. Since this is monthly percentage change, each row depends on the row before and goes beyond a single ROW_NUMBER/PARTITION solution because we have to use the previous calculated price. Clearly what is an easy sequential calculation in excel is a bit more difficult here. Any idea how to create forecasted price column in SQL?










share|improve this question
























  • WHere is the first 150 coming from?

    – Salman A
    Nov 12 '18 at 19:04











  • 150 = 50% * 100 + 100. Price from 1/1/18, plus the 50% price increase.

    – BenM
    Nov 12 '18 at 19:05











  • I believe you need to solve it with recursion. LAG/SUM OVER won't help here.

    – Salman A
    Nov 13 '18 at 6:05













1












1








1


1






I'm trying to find a way to apply monthly percentage changes to forecast pricing. I set my problem up in excel to make it a bit more clear. I'm using SQL Server 2017.



PricingTable Sample Data



We'll say all months before 9/1/18 are historical and 9/1/18 and beyond are forecasts. I need to calculate the forecast price (shaded in yellow on the sample data) using...



Forecast Price = (Previous Row Forecast Price * Pct Change) + Previous Row Forecast Price


Just to be clear, the yellow shaded prices do not exist in my data yet. That is what I am trying to have my query calculate. Since this is monthly percentage change, each row depends on the row before and goes beyond a single ROW_NUMBER/PARTITION solution because we have to use the previous calculated price. Clearly what is an easy sequential calculation in excel is a bit more difficult here. Any idea how to create forecasted price column in SQL?










share|improve this question
















I'm trying to find a way to apply monthly percentage changes to forecast pricing. I set my problem up in excel to make it a bit more clear. I'm using SQL Server 2017.



PricingTable Sample Data



We'll say all months before 9/1/18 are historical and 9/1/18 and beyond are forecasts. I need to calculate the forecast price (shaded in yellow on the sample data) using...



Forecast Price = (Previous Row Forecast Price * Pct Change) + Previous Row Forecast Price


Just to be clear, the yellow shaded prices do not exist in my data yet. That is what I am trying to have my query calculate. Since this is monthly percentage change, each row depends on the row before and goes beyond a single ROW_NUMBER/PARTITION solution because we have to use the previous calculated price. Clearly what is an easy sequential calculation in excel is a bit more difficult here. Any idea how to create forecasted price column in SQL?







sql sql-server tsql forecast






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 6:41









Salman A

177k66337427




177k66337427










asked Nov 12 '18 at 18:49









jslater41jslater41

83




83












  • WHere is the first 150 coming from?

    – Salman A
    Nov 12 '18 at 19:04











  • 150 = 50% * 100 + 100. Price from 1/1/18, plus the 50% price increase.

    – BenM
    Nov 12 '18 at 19:05











  • I believe you need to solve it with recursion. LAG/SUM OVER won't help here.

    – Salman A
    Nov 13 '18 at 6:05

















  • WHere is the first 150 coming from?

    – Salman A
    Nov 12 '18 at 19:04











  • 150 = 50% * 100 + 100. Price from 1/1/18, plus the 50% price increase.

    – BenM
    Nov 12 '18 at 19:05











  • I believe you need to solve it with recursion. LAG/SUM OVER won't help here.

    – Salman A
    Nov 13 '18 at 6:05
















WHere is the first 150 coming from?

– Salman A
Nov 12 '18 at 19:04





WHere is the first 150 coming from?

– Salman A
Nov 12 '18 at 19:04













150 = 50% * 100 + 100. Price from 1/1/18, plus the 50% price increase.

– BenM
Nov 12 '18 at 19:05





150 = 50% * 100 + 100. Price from 1/1/18, plus the 50% price increase.

– BenM
Nov 12 '18 at 19:05













I believe you need to solve it with recursion. LAG/SUM OVER won't help here.

– Salman A
Nov 13 '18 at 6:05





I believe you need to solve it with recursion. LAG/SUM OVER won't help here.

– Salman A
Nov 13 '18 at 6:05












2 Answers
2






active

oldest

votes


















0














You need to use a recursive CTE. That is one of the easier ways to look at the value of a calculated value from previous row:



DECLARE @t TABLE(Date DATE, ID VARCHAR(10), Price DECIMAL(10, 2), PctChange DECIMAL(10, 2));
INSERT INTO @t VALUES
('2018-01-01', 'ABC', 100, NULL),
('2018-01-02', 'ABC', 150, 50.00),
('2018-01-03', 'ABC', 130, -13.33),
('2018-01-04', 'ABC', 120, -07.69),
('2018-01-05', 'ABC', 110, -08.33),
('2018-01-06', 'ABC', 120, 9.09),
('2018-01-07', 'ABC', 120, 0.00),
('2018-01-08', 'ABC', 100, -16.67),
('2018-01-09', 'ABC', NULL, -07.21),
('2018-01-10', 'ABC', NULL, 1.31),
('2018-01-11', 'ABC', NULL, 6.38),
('2018-01-12', 'ABC', NULL, -30.00),
('2019-01-01', 'ABC', NULL, 14.29),
('2019-01-02', 'ABC', NULL, 5.27);

WITH ncte AS (
-- number the rows sequentially without gaps
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Date) AS rn
FROM @t
), rcte AS (
-- find first row in each group
SELECT *, Price AS ForecastedPrice
FROM ncte AS base
WHERE rn = 1
UNION ALL
-- find next row for each group from prev rows
SELECT curr.*, CAST(prev.ForecastedPrice * (1 + curr.PctChange / 100) AS DECIMAL(10, 2))
FROM ncte AS curr
INNER JOIN rcte AS prev ON curr.ID = prev.ID AND curr.rn = prev.rn + 1
)
SELECT *
FROM rcte
ORDER BY ID, rn


Result:



| Date | ID | Price | PctChange | rn | ForecastedPrice |
|------------|-----|--------|-----------|----|-----------------|
| 2018-01-01 | ABC | 100.00 | NULL | 1 | 100.00 |
| 2018-01-02 | ABC | 150.00 | 50.00 | 2 | 150.00 |
| 2018-01-03 | ABC | 130.00 | -13.33 | 3 | 130.01 |
| 2018-01-04 | ABC | 120.00 | -7.69 | 4 | 120.01 |
| 2018-01-05 | ABC | 110.00 | -8.33 | 5 | 110.01 |
| 2018-01-06 | ABC | 120.00 | 9.09 | 6 | 120.01 |
| 2018-01-07 | ABC | 120.00 | 0.00 | 7 | 120.01 |
| 2018-01-08 | ABC | 100.00 | -16.67 | 8 | 100.00 |
| 2018-01-09 | ABC | NULL | -7.21 | 9 | 92.79 |
| 2018-01-10 | ABC | NULL | 1.31 | 10 | 94.01 |
| 2018-01-11 | ABC | NULL | 6.38 | 11 | 100.01 |
| 2018-01-12 | ABC | NULL | -30.00 | 12 | 70.01 |
| 2019-01-01 | ABC | NULL | 14.29 | 13 | 80.01 |
| 2019-01-02 | ABC | NULL | 5.27 | 14 | 84.23 |


Demo on DB Fiddle






share|improve this answer























  • Yea this works well. First time using recursion. However, if we apply this to a couple million rows I think processing will be extremely slow, correct?

    – jslater41
    Nov 13 '18 at 15:11











  • Yes it is iterative and difficult or perhaps impossible to optimize. Besides slowness, I am worried about recursion limit... SQL server stops after 32,768 iterations max.

    – Salman A
    Nov 13 '18 at 18:15


















0














In SQL Server you can access values of previous / next rows by using the windowing functions LAG and LEAD. You need to define the order of the rows by specifying it in the OVER clause. You may need to wrap the select query, that returns prev/next values in a derived table or CTE, and then select from it and calculate your forecasts.



with cte as (SELECT [Date], Price, LAG(Price, 1) over(order by [Date]) as PrevPrice from TABLE)
select [Date], Price, Price - PrevPrice as PriceChange from cte





share|improve this answer























  • Awesome. I'll try this later. One thing I didn't add in the sample data is multiple IDs over the same time span. I'm guessing this would be some sort of partition in the over statement or just a group by. I'll report back if I cant figure that part out.

    – jslater41
    Nov 12 '18 at 19:28











  • If I got you point correctly, you need to add "partition by" in the over clause LAG(Price, 1) over(partition by ElementId order by [Date]) as PrevPriceForTheSameElementType

    – Andrey Nikolov
    Nov 12 '18 at 20:30










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268337%2fcreate-calculated-value-based-on-calculated-value-inside-previous-row%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














You need to use a recursive CTE. That is one of the easier ways to look at the value of a calculated value from previous row:



DECLARE @t TABLE(Date DATE, ID VARCHAR(10), Price DECIMAL(10, 2), PctChange DECIMAL(10, 2));
INSERT INTO @t VALUES
('2018-01-01', 'ABC', 100, NULL),
('2018-01-02', 'ABC', 150, 50.00),
('2018-01-03', 'ABC', 130, -13.33),
('2018-01-04', 'ABC', 120, -07.69),
('2018-01-05', 'ABC', 110, -08.33),
('2018-01-06', 'ABC', 120, 9.09),
('2018-01-07', 'ABC', 120, 0.00),
('2018-01-08', 'ABC', 100, -16.67),
('2018-01-09', 'ABC', NULL, -07.21),
('2018-01-10', 'ABC', NULL, 1.31),
('2018-01-11', 'ABC', NULL, 6.38),
('2018-01-12', 'ABC', NULL, -30.00),
('2019-01-01', 'ABC', NULL, 14.29),
('2019-01-02', 'ABC', NULL, 5.27);

WITH ncte AS (
-- number the rows sequentially without gaps
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Date) AS rn
FROM @t
), rcte AS (
-- find first row in each group
SELECT *, Price AS ForecastedPrice
FROM ncte AS base
WHERE rn = 1
UNION ALL
-- find next row for each group from prev rows
SELECT curr.*, CAST(prev.ForecastedPrice * (1 + curr.PctChange / 100) AS DECIMAL(10, 2))
FROM ncte AS curr
INNER JOIN rcte AS prev ON curr.ID = prev.ID AND curr.rn = prev.rn + 1
)
SELECT *
FROM rcte
ORDER BY ID, rn


Result:



| Date | ID | Price | PctChange | rn | ForecastedPrice |
|------------|-----|--------|-----------|----|-----------------|
| 2018-01-01 | ABC | 100.00 | NULL | 1 | 100.00 |
| 2018-01-02 | ABC | 150.00 | 50.00 | 2 | 150.00 |
| 2018-01-03 | ABC | 130.00 | -13.33 | 3 | 130.01 |
| 2018-01-04 | ABC | 120.00 | -7.69 | 4 | 120.01 |
| 2018-01-05 | ABC | 110.00 | -8.33 | 5 | 110.01 |
| 2018-01-06 | ABC | 120.00 | 9.09 | 6 | 120.01 |
| 2018-01-07 | ABC | 120.00 | 0.00 | 7 | 120.01 |
| 2018-01-08 | ABC | 100.00 | -16.67 | 8 | 100.00 |
| 2018-01-09 | ABC | NULL | -7.21 | 9 | 92.79 |
| 2018-01-10 | ABC | NULL | 1.31 | 10 | 94.01 |
| 2018-01-11 | ABC | NULL | 6.38 | 11 | 100.01 |
| 2018-01-12 | ABC | NULL | -30.00 | 12 | 70.01 |
| 2019-01-01 | ABC | NULL | 14.29 | 13 | 80.01 |
| 2019-01-02 | ABC | NULL | 5.27 | 14 | 84.23 |


Demo on DB Fiddle






share|improve this answer























  • Yea this works well. First time using recursion. However, if we apply this to a couple million rows I think processing will be extremely slow, correct?

    – jslater41
    Nov 13 '18 at 15:11











  • Yes it is iterative and difficult or perhaps impossible to optimize. Besides slowness, I am worried about recursion limit... SQL server stops after 32,768 iterations max.

    – Salman A
    Nov 13 '18 at 18:15















0














You need to use a recursive CTE. That is one of the easier ways to look at the value of a calculated value from previous row:



DECLARE @t TABLE(Date DATE, ID VARCHAR(10), Price DECIMAL(10, 2), PctChange DECIMAL(10, 2));
INSERT INTO @t VALUES
('2018-01-01', 'ABC', 100, NULL),
('2018-01-02', 'ABC', 150, 50.00),
('2018-01-03', 'ABC', 130, -13.33),
('2018-01-04', 'ABC', 120, -07.69),
('2018-01-05', 'ABC', 110, -08.33),
('2018-01-06', 'ABC', 120, 9.09),
('2018-01-07', 'ABC', 120, 0.00),
('2018-01-08', 'ABC', 100, -16.67),
('2018-01-09', 'ABC', NULL, -07.21),
('2018-01-10', 'ABC', NULL, 1.31),
('2018-01-11', 'ABC', NULL, 6.38),
('2018-01-12', 'ABC', NULL, -30.00),
('2019-01-01', 'ABC', NULL, 14.29),
('2019-01-02', 'ABC', NULL, 5.27);

WITH ncte AS (
-- number the rows sequentially without gaps
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Date) AS rn
FROM @t
), rcte AS (
-- find first row in each group
SELECT *, Price AS ForecastedPrice
FROM ncte AS base
WHERE rn = 1
UNION ALL
-- find next row for each group from prev rows
SELECT curr.*, CAST(prev.ForecastedPrice * (1 + curr.PctChange / 100) AS DECIMAL(10, 2))
FROM ncte AS curr
INNER JOIN rcte AS prev ON curr.ID = prev.ID AND curr.rn = prev.rn + 1
)
SELECT *
FROM rcte
ORDER BY ID, rn


Result:



| Date | ID | Price | PctChange | rn | ForecastedPrice |
|------------|-----|--------|-----------|----|-----------------|
| 2018-01-01 | ABC | 100.00 | NULL | 1 | 100.00 |
| 2018-01-02 | ABC | 150.00 | 50.00 | 2 | 150.00 |
| 2018-01-03 | ABC | 130.00 | -13.33 | 3 | 130.01 |
| 2018-01-04 | ABC | 120.00 | -7.69 | 4 | 120.01 |
| 2018-01-05 | ABC | 110.00 | -8.33 | 5 | 110.01 |
| 2018-01-06 | ABC | 120.00 | 9.09 | 6 | 120.01 |
| 2018-01-07 | ABC | 120.00 | 0.00 | 7 | 120.01 |
| 2018-01-08 | ABC | 100.00 | -16.67 | 8 | 100.00 |
| 2018-01-09 | ABC | NULL | -7.21 | 9 | 92.79 |
| 2018-01-10 | ABC | NULL | 1.31 | 10 | 94.01 |
| 2018-01-11 | ABC | NULL | 6.38 | 11 | 100.01 |
| 2018-01-12 | ABC | NULL | -30.00 | 12 | 70.01 |
| 2019-01-01 | ABC | NULL | 14.29 | 13 | 80.01 |
| 2019-01-02 | ABC | NULL | 5.27 | 14 | 84.23 |


Demo on DB Fiddle






share|improve this answer























  • Yea this works well. First time using recursion. However, if we apply this to a couple million rows I think processing will be extremely slow, correct?

    – jslater41
    Nov 13 '18 at 15:11











  • Yes it is iterative and difficult or perhaps impossible to optimize. Besides slowness, I am worried about recursion limit... SQL server stops after 32,768 iterations max.

    – Salman A
    Nov 13 '18 at 18:15













0












0








0







You need to use a recursive CTE. That is one of the easier ways to look at the value of a calculated value from previous row:



DECLARE @t TABLE(Date DATE, ID VARCHAR(10), Price DECIMAL(10, 2), PctChange DECIMAL(10, 2));
INSERT INTO @t VALUES
('2018-01-01', 'ABC', 100, NULL),
('2018-01-02', 'ABC', 150, 50.00),
('2018-01-03', 'ABC', 130, -13.33),
('2018-01-04', 'ABC', 120, -07.69),
('2018-01-05', 'ABC', 110, -08.33),
('2018-01-06', 'ABC', 120, 9.09),
('2018-01-07', 'ABC', 120, 0.00),
('2018-01-08', 'ABC', 100, -16.67),
('2018-01-09', 'ABC', NULL, -07.21),
('2018-01-10', 'ABC', NULL, 1.31),
('2018-01-11', 'ABC', NULL, 6.38),
('2018-01-12', 'ABC', NULL, -30.00),
('2019-01-01', 'ABC', NULL, 14.29),
('2019-01-02', 'ABC', NULL, 5.27);

WITH ncte AS (
-- number the rows sequentially without gaps
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Date) AS rn
FROM @t
), rcte AS (
-- find first row in each group
SELECT *, Price AS ForecastedPrice
FROM ncte AS base
WHERE rn = 1
UNION ALL
-- find next row for each group from prev rows
SELECT curr.*, CAST(prev.ForecastedPrice * (1 + curr.PctChange / 100) AS DECIMAL(10, 2))
FROM ncte AS curr
INNER JOIN rcte AS prev ON curr.ID = prev.ID AND curr.rn = prev.rn + 1
)
SELECT *
FROM rcte
ORDER BY ID, rn


Result:



| Date | ID | Price | PctChange | rn | ForecastedPrice |
|------------|-----|--------|-----------|----|-----------------|
| 2018-01-01 | ABC | 100.00 | NULL | 1 | 100.00 |
| 2018-01-02 | ABC | 150.00 | 50.00 | 2 | 150.00 |
| 2018-01-03 | ABC | 130.00 | -13.33 | 3 | 130.01 |
| 2018-01-04 | ABC | 120.00 | -7.69 | 4 | 120.01 |
| 2018-01-05 | ABC | 110.00 | -8.33 | 5 | 110.01 |
| 2018-01-06 | ABC | 120.00 | 9.09 | 6 | 120.01 |
| 2018-01-07 | ABC | 120.00 | 0.00 | 7 | 120.01 |
| 2018-01-08 | ABC | 100.00 | -16.67 | 8 | 100.00 |
| 2018-01-09 | ABC | NULL | -7.21 | 9 | 92.79 |
| 2018-01-10 | ABC | NULL | 1.31 | 10 | 94.01 |
| 2018-01-11 | ABC | NULL | 6.38 | 11 | 100.01 |
| 2018-01-12 | ABC | NULL | -30.00 | 12 | 70.01 |
| 2019-01-01 | ABC | NULL | 14.29 | 13 | 80.01 |
| 2019-01-02 | ABC | NULL | 5.27 | 14 | 84.23 |


Demo on DB Fiddle






share|improve this answer













You need to use a recursive CTE. That is one of the easier ways to look at the value of a calculated value from previous row:



DECLARE @t TABLE(Date DATE, ID VARCHAR(10), Price DECIMAL(10, 2), PctChange DECIMAL(10, 2));
INSERT INTO @t VALUES
('2018-01-01', 'ABC', 100, NULL),
('2018-01-02', 'ABC', 150, 50.00),
('2018-01-03', 'ABC', 130, -13.33),
('2018-01-04', 'ABC', 120, -07.69),
('2018-01-05', 'ABC', 110, -08.33),
('2018-01-06', 'ABC', 120, 9.09),
('2018-01-07', 'ABC', 120, 0.00),
('2018-01-08', 'ABC', 100, -16.67),
('2018-01-09', 'ABC', NULL, -07.21),
('2018-01-10', 'ABC', NULL, 1.31),
('2018-01-11', 'ABC', NULL, 6.38),
('2018-01-12', 'ABC', NULL, -30.00),
('2019-01-01', 'ABC', NULL, 14.29),
('2019-01-02', 'ABC', NULL, 5.27);

WITH ncte AS (
-- number the rows sequentially without gaps
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Date) AS rn
FROM @t
), rcte AS (
-- find first row in each group
SELECT *, Price AS ForecastedPrice
FROM ncte AS base
WHERE rn = 1
UNION ALL
-- find next row for each group from prev rows
SELECT curr.*, CAST(prev.ForecastedPrice * (1 + curr.PctChange / 100) AS DECIMAL(10, 2))
FROM ncte AS curr
INNER JOIN rcte AS prev ON curr.ID = prev.ID AND curr.rn = prev.rn + 1
)
SELECT *
FROM rcte
ORDER BY ID, rn


Result:



| Date | ID | Price | PctChange | rn | ForecastedPrice |
|------------|-----|--------|-----------|----|-----------------|
| 2018-01-01 | ABC | 100.00 | NULL | 1 | 100.00 |
| 2018-01-02 | ABC | 150.00 | 50.00 | 2 | 150.00 |
| 2018-01-03 | ABC | 130.00 | -13.33 | 3 | 130.01 |
| 2018-01-04 | ABC | 120.00 | -7.69 | 4 | 120.01 |
| 2018-01-05 | ABC | 110.00 | -8.33 | 5 | 110.01 |
| 2018-01-06 | ABC | 120.00 | 9.09 | 6 | 120.01 |
| 2018-01-07 | ABC | 120.00 | 0.00 | 7 | 120.01 |
| 2018-01-08 | ABC | 100.00 | -16.67 | 8 | 100.00 |
| 2018-01-09 | ABC | NULL | -7.21 | 9 | 92.79 |
| 2018-01-10 | ABC | NULL | 1.31 | 10 | 94.01 |
| 2018-01-11 | ABC | NULL | 6.38 | 11 | 100.01 |
| 2018-01-12 | ABC | NULL | -30.00 | 12 | 70.01 |
| 2019-01-01 | ABC | NULL | 14.29 | 13 | 80.01 |
| 2019-01-02 | ABC | NULL | 5.27 | 14 | 84.23 |


Demo on DB Fiddle







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 '18 at 6:45









Salman ASalman A

177k66337427




177k66337427












  • Yea this works well. First time using recursion. However, if we apply this to a couple million rows I think processing will be extremely slow, correct?

    – jslater41
    Nov 13 '18 at 15:11











  • Yes it is iterative and difficult or perhaps impossible to optimize. Besides slowness, I am worried about recursion limit... SQL server stops after 32,768 iterations max.

    – Salman A
    Nov 13 '18 at 18:15

















  • Yea this works well. First time using recursion. However, if we apply this to a couple million rows I think processing will be extremely slow, correct?

    – jslater41
    Nov 13 '18 at 15:11











  • Yes it is iterative and difficult or perhaps impossible to optimize. Besides slowness, I am worried about recursion limit... SQL server stops after 32,768 iterations max.

    – Salman A
    Nov 13 '18 at 18:15
















Yea this works well. First time using recursion. However, if we apply this to a couple million rows I think processing will be extremely slow, correct?

– jslater41
Nov 13 '18 at 15:11





Yea this works well. First time using recursion. However, if we apply this to a couple million rows I think processing will be extremely slow, correct?

– jslater41
Nov 13 '18 at 15:11













Yes it is iterative and difficult or perhaps impossible to optimize. Besides slowness, I am worried about recursion limit... SQL server stops after 32,768 iterations max.

– Salman A
Nov 13 '18 at 18:15





Yes it is iterative and difficult or perhaps impossible to optimize. Besides slowness, I am worried about recursion limit... SQL server stops after 32,768 iterations max.

– Salman A
Nov 13 '18 at 18:15













0














In SQL Server you can access values of previous / next rows by using the windowing functions LAG and LEAD. You need to define the order of the rows by specifying it in the OVER clause. You may need to wrap the select query, that returns prev/next values in a derived table or CTE, and then select from it and calculate your forecasts.



with cte as (SELECT [Date], Price, LAG(Price, 1) over(order by [Date]) as PrevPrice from TABLE)
select [Date], Price, Price - PrevPrice as PriceChange from cte





share|improve this answer























  • Awesome. I'll try this later. One thing I didn't add in the sample data is multiple IDs over the same time span. I'm guessing this would be some sort of partition in the over statement or just a group by. I'll report back if I cant figure that part out.

    – jslater41
    Nov 12 '18 at 19:28











  • If I got you point correctly, you need to add "partition by" in the over clause LAG(Price, 1) over(partition by ElementId order by [Date]) as PrevPriceForTheSameElementType

    – Andrey Nikolov
    Nov 12 '18 at 20:30















0














In SQL Server you can access values of previous / next rows by using the windowing functions LAG and LEAD. You need to define the order of the rows by specifying it in the OVER clause. You may need to wrap the select query, that returns prev/next values in a derived table or CTE, and then select from it and calculate your forecasts.



with cte as (SELECT [Date], Price, LAG(Price, 1) over(order by [Date]) as PrevPrice from TABLE)
select [Date], Price, Price - PrevPrice as PriceChange from cte





share|improve this answer























  • Awesome. I'll try this later. One thing I didn't add in the sample data is multiple IDs over the same time span. I'm guessing this would be some sort of partition in the over statement or just a group by. I'll report back if I cant figure that part out.

    – jslater41
    Nov 12 '18 at 19:28











  • If I got you point correctly, you need to add "partition by" in the over clause LAG(Price, 1) over(partition by ElementId order by [Date]) as PrevPriceForTheSameElementType

    – Andrey Nikolov
    Nov 12 '18 at 20:30













0












0








0







In SQL Server you can access values of previous / next rows by using the windowing functions LAG and LEAD. You need to define the order of the rows by specifying it in the OVER clause. You may need to wrap the select query, that returns prev/next values in a derived table or CTE, and then select from it and calculate your forecasts.



with cte as (SELECT [Date], Price, LAG(Price, 1) over(order by [Date]) as PrevPrice from TABLE)
select [Date], Price, Price - PrevPrice as PriceChange from cte





share|improve this answer













In SQL Server you can access values of previous / next rows by using the windowing functions LAG and LEAD. You need to define the order of the rows by specifying it in the OVER clause. You may need to wrap the select query, that returns prev/next values in a derived table or CTE, and then select from it and calculate your forecasts.



with cte as (SELECT [Date], Price, LAG(Price, 1) over(order by [Date]) as PrevPrice from TABLE)
select [Date], Price, Price - PrevPrice as PriceChange from cte






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 12 '18 at 19:01









Andrey NikolovAndrey Nikolov

3,7581621




3,7581621












  • Awesome. I'll try this later. One thing I didn't add in the sample data is multiple IDs over the same time span. I'm guessing this would be some sort of partition in the over statement or just a group by. I'll report back if I cant figure that part out.

    – jslater41
    Nov 12 '18 at 19:28











  • If I got you point correctly, you need to add "partition by" in the over clause LAG(Price, 1) over(partition by ElementId order by [Date]) as PrevPriceForTheSameElementType

    – Andrey Nikolov
    Nov 12 '18 at 20:30

















  • Awesome. I'll try this later. One thing I didn't add in the sample data is multiple IDs over the same time span. I'm guessing this would be some sort of partition in the over statement or just a group by. I'll report back if I cant figure that part out.

    – jslater41
    Nov 12 '18 at 19:28











  • If I got you point correctly, you need to add "partition by" in the over clause LAG(Price, 1) over(partition by ElementId order by [Date]) as PrevPriceForTheSameElementType

    – Andrey Nikolov
    Nov 12 '18 at 20:30
















Awesome. I'll try this later. One thing I didn't add in the sample data is multiple IDs over the same time span. I'm guessing this would be some sort of partition in the over statement or just a group by. I'll report back if I cant figure that part out.

– jslater41
Nov 12 '18 at 19:28





Awesome. I'll try this later. One thing I didn't add in the sample data is multiple IDs over the same time span. I'm guessing this would be some sort of partition in the over statement or just a group by. I'll report back if I cant figure that part out.

– jslater41
Nov 12 '18 at 19:28













If I got you point correctly, you need to add "partition by" in the over clause LAG(Price, 1) over(partition by ElementId order by [Date]) as PrevPriceForTheSameElementType

– Andrey Nikolov
Nov 12 '18 at 20:30





If I got you point correctly, you need to add "partition by" in the over clause LAG(Price, 1) over(partition by ElementId order by [Date]) as PrevPriceForTheSameElementType

– Andrey Nikolov
Nov 12 '18 at 20:30

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268337%2fcreate-calculated-value-based-on-calculated-value-inside-previous-row%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Use pre created SQLite database for Android project in kotlin

Darth Vader #20

Ondo