Получить изменение цены для всех самых последних цен в T-SQL

Мне было поручено написать приложение, которое позволит пользователю выполнять поиск в таблице цен, где цены уникальны по трем различным ключам, скажем, состояние, издатель и тип (может быть любое количество строк с одинаковым значением ключа для любого из 3 полей, но есть только одна строка с указанием state= 'Ohio', publisher= 'Bob' и type= 'silic'). Когда пользователь выбирает состояние и издателя, ему представляется список всех типов с этим состоянием и издателем. Я запускаю хранимую процедуру, чтобы вытащить эти предметы, и я вытягиваю самую последнюю цену, но мне также нужно вытащить вторую самую последнюю цену и выполнить математику, чтобы отобразить изменение цены для пользователя. В настоящее время я создал следующую функцию, но она замедляет мою хранимую процедуру от 1 до 40 секунд, в зависимости от настроения сервера при выполнении.

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

Есть ли более эффективный способ сделать это, поэтому я не делаю два запроса на строку в хранимой процедуре?

Заранее благодарю за любую помощь, и дайте мне знать, если я могу уточнить что-нибудь еще!

2 ответа

Решение

Попробуйте использовать аналитическую функцию LEAD и использовать ее для возврата данных в таблицу. Я прошу прощения, если это не точно, но с некоторыми изменениями я уверен, что это даст вам то, что вы ищете.

Пытаться:

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

Попробуйте это пожалуйста:

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
Другие вопросы по тегам