简体   繁体   中英

Get the change in price for all most recent prices in T-SQL

I've been tasked with writing an application that will allow the user to search a table of prices, where prices are unique on 3 different keys, say state , publisher , and type (there may be any number of rows with the same key value for any of the 3 fields, but there is only one row with state ='Ohio', publisher ='Bob', and type ='silicon'). When a user selects the state and publisher , they are presented a list of all of the types with that state and publisher . I run a stored procedure to pull these items, and I am pulling the most recent price, but I also need to pull the second most recent price and do math to get the change in price to display to the user. currently, I created the following function, but it slows down my stored procedure by anywhere from 1 to 40 seconds, depending on the mood of the server when executed.

BEGIN
    -- Declare the return variable here
    DECLARE @priceChange float
    DECLARE @currentPriceDate date
    DECLARE @currentPrice float
    DECLARE @previousPrice float

    -- Add the T-SQL statements to compute the return value here
    SELECT TOP 1 @currentPriceDate=PriceDate ,@CurrentPrice=MarketPrice
        FROM MarketPrice_Table
            LEFT JOIN PriceEffectiveDate_Table ON MarketPrice_Table.PriceDate = PriceEffectiveDate_Table.EffectiveDate
                AND MarketPrice_Table.PublisherID = PriceEffectiveDate_Table.PublisherID
        WHERE TypeID = @TypeID
        AND MarketPrice_Table.PublisherID = @PublisherID
        AND MarketPrice_Table.StateID = @StateID
        ORDER BY PriceDate DESC;

    SET @previousPrice = (SELECT TOP 1 MarketPrice 
        FROM MarketPrice_Table
            LEFT JOIN PriceEffectiveDate_Table ON MarketPrice_Table.PriceDate = PriceEffectiveDate_Table.EffectiveDate
                AND MarketPrice_Table.PublisherID = PriceEffectiveDate_Table.PublisherID
        WHERE TypeID = @TypeID
        AND MarketPrice_Table.PublisherID = @PublisherID
        AND MarketPrice_Table.StateID = @StateID
        AND MarketPrice_Table.PriceDate <> @currentPriceDate
        ORDER BY PriceDate DESC);

    SET @priceChange = @currentPrice - @previousPrice;

    -- Return the result of the function
    RETURN @priceChange

END

Is there a more efficient way to do this so I am not making two queries per row in the stored procedure?

Thank you in advance for any help, and let me know if I can clarify anything further!

Try this please:

BEGIN
-- Declare the return variable here
DECLARE @priceChange float
DECLARE @currentPriceDate varchar(8)
DECLARE @currentPrice float
DECLARE @previousPrice float

-- Add the T-SQL statements to compute the return value here
SELECT TOP 1 @currentPriceDate=Convert(varchar,PriceDate,112) ,@CurrentPrice=MarketPrice
    FROM MarketPrice_Table
        LEFT JOIN PriceEffectiveDate_Table ON Convert(varchar,MarketPrice_Table.PriceDate,112) = Convert(varchar,PriceEffectiveDate_Table.EffectiveDate,112)
            AND MarketPrice_Table.PublisherID = PriceEffectiveDate_Table.PublisherID
    WHERE TypeID = @TypeID
    AND MarketPrice_Table.PublisherID = @PublisherID
    AND MarketPrice_Table.StateID = @StateID
    ORDER BY PriceDate DESC;

SET @previousPrice = (SELECT TOP 1 MarketPrice 
    FROM MarketPrice_Table
        LEFT JOIN PriceEffectiveDate_Table ON Convert(varchar,MarketPrice_Table.PriceDate,112) = Convert(varchar,PriceEffectiveDate_Table.EffectiveDate)
            AND MarketPrice_Table.PublisherID = PriceEffectiveDate_Table.PublisherID
    WHERE TypeID = @TypeID
    AND MarketPrice_Table.PublisherID = @PublisherID
    AND MarketPrice_Table.StateID = @StateID
    AND Convert(varchar,MarketPrice_Table.PriceDate,112) <> @currentPriceDate
    ORDER BY PriceDate DESC);

SET @priceChange = @currentPrice - @previousPrice;

-- Return the result of the function
RETURN @priceChange

END

Try using the LEAD analytically function and use it return the data in a table. I apologize if this not exact but with some modification i'm sure it will give you what you're looking for.

Try:

DECLARE @priceChange float
DECLARE @currentPriceDate date
DECLARE @currentPrice float
DECLARE @previousPrice FLOAT

SELECT
    *
FROM
    (   
        SELECT 
            ROW_NUMBER() OVER (PARTITION BY MarketPrice_Table.StateID, MarketPrice_Table.PublisherID, TypeID ORDER BY PriceDate DESC) AS RowNum,
            MarketPrice_Table.StateID,
            MarketPrice_Table.PublisherID,
            TypeID,
            PriceDate, 
            MarketPrice AS CurrentPrice,
            LEAD(MarketPrice) OVER (PARTITION BY MarketPrice_Table.StateID, MarketPrice_Table.PublisherID, TypeID ORDER BY PriceDate DESC) AS PreviousPrice,
            MarketPrice - ISNULL(LEAD(MarketPrice) OVER (PARTITION BY MarketPrice_Table.StateID, MarketPrice_Table.PublisherID, TypeID ORDER BY PriceDate DESC), 0) AS PriceChange
        FROM 
            MarketPrice_Table
            LEFT JOIN PriceEffectiveDate_Table 
                ON MarketPrice_Table.PriceDate = PriceEffectiveDate_Table.EffectiveDate
                AND MarketPrice_Table.PublisherID = PriceEffectiveDate_Table.PublisherID
        WHERE 
            TypeID = @TypeID AND 
            MarketPrice_Table.PublisherID = @PublisherID AND 
            MarketPrice_Table.StateID = @StateID
    ) r
WHERE
    r.RowNum = 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM