Update previous close price.

  • First of all, the reason why your code turned back into a slow monster is because you used a While Loop... AGAIN! If you're gonna keep doing that to perfectly fast code, then I'm all done. 😉

    Second, the only reason why the code might not be right is because the assumptions that you implied with your test data that I took to heart are not correct.

    So, what is the actual condition of the data? [font="Arial Black"]Is the Detail_ID in sorted order by Inventory_Code and Detail_Date or not? [/font]

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • The Detail_ID is in sorted order by Inventory_Code and Detail_Date.

    Why is that when I pass a parameter(Inventory_Code) values are updated correctly? If it was not sorted by Inventory_Code and Detail_Date. Only problem arises is when I execute the same proc for all the Inventory_code.

  • Ashwin M N (2/25/2009)


    The Detail_ID is in sorted order by Inventory_Code and Detail_Date.

    Why is that when I pass a parameter(Inventory_Code) values are updated correctly? If it was not sorted by Inventory_Code and Detail_Date. Only problem arises is when I execute the same proc for all the Inventory_code.

    Dunno... I'll take a look.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Thanks Jack... lotta tension on this side, lately, and I had to make sure I wasn't tuggin' on a friend's chain.

    Phew! Jeff 😀

    Thought you were trying to poke the hornets nest again 😉

    Far away is close at hand in the images of elsewhere.
    Anon.

  • Alright, Ashwin... here's the whole shootin' match including your original posted table except that I included the clustered PK. I've verified that it returns exactly what your code did and they both do it correctly... so, what's the problem?

    --===== Conditionally drop the test table so we can easily rerun when needed

    IF OBJECT_ID('TempDB.dbo.Temp') IS NOT NULL

    DROP TABLE dbo.Temp

    GO

    --===== Recreate the test table, WITH A CLUSTERED PK

    CREATE TABLE dbo.Temp

    (

    Detail_ID NUMERIC(18,0) IDENTITY (1,1) NOT NULL ,

    Inventory_Code INT NULL ,

    Detail_Date DATETIME NULL ,

    Open_Price DECIMAL(10, 2) NULL ,

    Close_Price DECIMAL(10, 2) NULL ,

    Net_Volume BIGINT NULL ,

    Net_Value MONEY NULL ,

    Prev_close DECIMAL(10, 2) NULL

    CONSTRAINT PK_Temp_Detail_ID

    PRIMARY KEY CLUSTERED (Detail_ID)

    )

    GO

    --===== Populate the test table with the original data given in the post, but in an abbreviated fashion

    INSERT INTO dbo.Temp

    (Inventory_Code, Detail_Date, Open_Price, Close_Price, Net_Volume, Net_Value, Prev_close)

    SELECT 500002,'Feb 2 2009 12:00:00:000AM',480.00,455.10,24172,11192849.0000,NULL UNION ALL

    SELECT 500002,'Feb 3 2009 12:00:00:000AM',455.00,461.10,30706,14205560.0000,NULL UNION ALL

    SELECT 500002,'Feb 4 2009 12:00:00:000AM',468.00,463.30,29213,13633590.0000,NULL UNION ALL

    SELECT 500002,'Feb 5 2009 12:00:00:000AM',467.00,437.40,73687,32645242.0000,NULL UNION ALL

    SELECT 500002,'Feb 6 2009 12:00:00:000AM',441.00,454.90,43711,19665019.0000,NULL UNION ALL

    SELECT 500002,'Feb 9 2009 12:00:00:000AM',456.20,462.55,34984,15992694.0000,NULL UNION ALL

    SELECT 500002,'Feb 10 2009 12:00:00:000AM',465.00,456.25,44572,20485640.0000,NULL UNION ALL

    SELECT 500002,'Feb 11 2009 12:00:00:000AM',451.00,464.20,42001,19242949.0000,NULL UNION ALL

    SELECT 500002,'Feb 12 2009 12:00:00:000AM',467.00,455.10,54010,25109443.0000,NULL UNION ALL

    SELECT 500002,'Feb 13 2009 12:00:00:000AM',454.90,441.40,181224,81195470.0000,NULL UNION ALL

    SELECT 500002,'Feb 19 2009 12:00:00:000AM',409.00,393.20,89347,35786215.0000,NULL UNION ALL

    SELECT 500002,'Feb 16 2009 12:00:00:000AM',441.00,417.20,182342,77714063.0000,NULL UNION ALL

    SELECT 500002,'Feb 17 2009 12:00:00:000AM',410.00,405.15,161120,65317672.0000,NULL UNION ALL

    SELECT 500002,'Feb 18 2009 12:00:00:000AM',405.00,403.55,86998,35131698.0000,NULL

    --===== Add some data with a different inventory code.

    INSERT INTO Temp

    (Inventory_Code, Detail_Date, Open_Price, Close_Price, Net_Volume, Net_Value, Prev_Close)

    SELECT 500003, Detail_Date, Open_Price-5, Close_Price-5, Net_Volume-5, Net_Value-5, Prev_Close

    FROM dbo.Temp

    ORDER BY Detail_ID

    --===== Display the unmodified data as a sanity check

    SELECT * FROM dbo.Temp ORDER BY Detail_ID

    --===== Do the update to solve the problem =============================================================

    --===== Declare some obviously named variables

    DECLARE @Inventory_Code_To_Update INT

    SET @Inventory_Code_To_Update = 500003

    DECLARE @Prev_Close DECIMAL(10,2)

    DECLARE @Prev_Inventory_Code INT

    --===== Do the "data smear" using a "quirky update"

    UPDATE dbo.Temp

    SET @Prev_Close = Prev_Close = CASE WHEN Inventory_Code = @Prev_Inventory_Code

    THEN @Prev_Close

    ELSE Open_Price

    END,

    @Prev_Close = Close_Price,

    @Prev_Inventory_Code = Inventory_Code

    FROM dbo.Temp WITH(INDEX(0),TABLOCKX)

    WHERE Inventory_Code = @Inventory_Code_To_Update

    OR @Inventory_Code_To_Update IS NULL

    --===== Display the modified data to check the update

    SELECT * FROM dbo.Temp ORDER BY Detail_ID

    The big difference will be in the performance... the code above will blow the doors off any While loop solution.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Now continuing with the previous update. I have added a new column to the table with the column name Onweek_PercentageChange.

    Alter table temp add Onweek_percentageChange decimal(10,2).

    This column stores the value(percentage) change in close_price between todays close_price and close_price of the same inventory_code 5 days before.

    Inventory_Code Detail_Date Close_Price Onweek_PercentageChange

    500002 2009-02-02 455.10 NULL

    5000022009-02-03 461.10 NULL

    5000022009-02-04 463.30NULL

    5000022009-02-05 437.40NULL

    5000022009-02-06 454.90 ((454.90 - 455.10)/455.10)*100

    5000022009-02-09 462.55 ((462.55 - 461.10)/461.10)*100

    5000022009-02-10 456.25

    5000022009-02-11 464.20

    5000022009-02-12 455.10

    5000022009-02-13 441.40

    I tried to do a update query on this column using the same logic but failed.

    How can this be done using the logic mentioned below

    UPDATE dbo.Temp

    SET @Onweek_PercentageChange = Prev_Close = CASE WHEN Inventory_Code = @Prev_Inventory_Code - 5

    THEN @Prev_Close

    ELSE Open_Price

    END,

    @Onweek_PercentageChange = Close_Price,

    @Prev_Inventory_Code = Inventory_Code -5

    FROM dbo.Temp WITH(INDEX(0),TABLOCKX)

    WHERE Inventory_Code = @Inventory_Code_To_Update

    OR @Inventory_Code_To_Update IS NULL

  • Can you post the actual code you tried? The code you posted has no percentage calculations in it.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • I did for Oneday_percentchange column and the results are correct.

    The logic for that is given below.

    DECLARE @OneDay_percentChange DECIMAL(10,2)

    DECLARE @Inventory_code INT

    UPDATE dbo.Temp

    SET @OneDay_percentChange = OneDay_percentChange = CASE WHEN Inventory_code = @Inventory_code

    THEN ((Close_Price - @OneDay_percentChange)/@OneDay_percentChange) * 100

    ELSE null

    END,

    @OneDay_percentChange = Close_Price,

    @Inventory_code = Inventory_code

    FROM dbo.Temp WITH(INDEX(0),TABLOCKX)

    where Inventory_code = @Inventory_code

    But for OneWeek_PercentChange I not able to get desired results.

    DECLARE @OneWeek_PercentChange DECIMAL(10,2)

    DECLARE @Prev_Scrip_code INT

    UPDATE dbo.Temp

    SET @OneWeek_PercentChange = OneWeek_PercentChange = CASE WHEN Inventory_code = @Inventory_code - 5

    THEN ((Close_Price - @OneWeek_PercentChange)/@OneWeek_PercentChange) * 100

    ELSE null

    END,

    @OneWeek_PercentChange = Close_Price,

    @Inventory_code = Inventory_code

    FROM dbo.Temp WITH(INDEX(0),TABLOCKX)

    where Inventory_code = @Inventory_code

Viewing 8 posts - 16 through 22 (of 22 total)

You must be logged in to reply to this topic. Login to reply