【问题标题】:Get the change in price for all most recent prices in T-SQL获取 T-SQL 中所有最新价格的价格变化
【发布时间】:2014-10-23 20:14:56
【问题描述】:

我的任务是编写一个应用程序,该应用程序允许用户搜索价格表,其中价格在 3 个不同的键上是唯一的,例如 statepublishertype(对于 3 个字段中的任何一个,可能有任意数量的具有相同键值的行,但只有一行具有 state='Ohio' , publisher='Bob' 和 type='silicon')。当用户选择 statepublisher 时,他们会看到具有该 state 的所有 types 的列表和出版商。我运行一个存储过程来提取这些项目,并且我正在提取最近的价格,但我还需要提取第二个最近的价格并进行数学运算以将价格变化显示给用户。目前,我创建了以下函数,但它会使我的存储过程减慢 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

有没有更有效的方法来做到这一点,这样我就不会在存储过程中的每行进行两次查询?

提前感谢您的帮助,如果我能进一步澄清任何事情,请告诉我!

【问题讨论】:

  • 首先我建议你将日期转换为字符串 Convert(varchar,MarketPrice_Table.PriceDate,112) Convert(varchar,@currentPriceDate,112)

标签: sql sql-server tsql sql-server-2012 sql-function


【解决方案1】:

尝试使用 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

【讨论】:

  • 我目前正在实现这个方法,而且它看起来真的很快。它不会返回 CurrentPrice 和 PreviousPrice 之间的差异,所以我试图弄清楚如何从中得到它。如果我能得到这个工作,我会接受它作为答案。非常感谢!
  • 效果很好!谢谢!在阅读您的回复之前,我将Select * 更改为Select CurrentPrice-PreviousPrice,这也注意到了我所追求的结果。但是在查看执行时间之后,您的版本更快。再次感谢你!我整天都在为这个问题挠头!
【解决方案2】:

请试试这个:

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

【讨论】:

    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 2016-08-11
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多