最新和第二个最新价格的差异

时间:2011-07-12 18:51:03

标签: sql sql-server sql-server-2008

我有两张表如下:

Commodity
---------
Id        Name
1         Test 
2         SecondTest

CommodityPrice
--------------
Id      CommodityID    Price     EffectiveDate
0            1         0.66      05/01/2011
1            1         1.00      06/01/2011
2            1         1.50      07/01/2011
3            2         3.00      05/01/2011         
4            2         5.00      06/01/2011
5            2         10.00     07/01/2011

我正在尝试使用以下输出编写查询:

Result
-------
Name          PriceChange
Test          0.50
SecondTest    5.00

我有这个查询得到最近的价格,但它还没有处理价格差异。

SELECT c1.Name, cp1.Price
FROM Commodities c1
INNER JOIN CommodityPrices cp1
ON c1.Id = cp1.CommodityId
WHERE EffectiveDate = 
(SELECT MAX(cp2.EffectiveDate)
FROM CommodityPrices cp2
WHERE c1.Id = cp2.CommodityId);

我想找出商品最近两个价格之间的价格差异。请注意,这应该比最近两次更早地忽略价格。

2 个答案:

答案 0 :(得分:2)

这假设SQL 2005或更高版本。只需使用ROW NUMBER为行分配数字,然后加入ON a.id = b.id AND b.rn = a.rn - 1

WITH
     cte 
     AS (SELECT c.id, 
                c.name, 
                cp.price, 
                cp.effectivedate, 
                Row_number() OVER (PARTITION BY c.id ORDER BY cp.effectivedate 
                DESC) 
                rn 
         FROM   commodity c 
                INNER JOIN commodityprice cp 
                  ON c.id = cp.commodityid) 
SELECT a.name, 
       b.price - a.price pricechange 
FROM   cte a 
       INNER JOIN cte b 
         ON a.id = b.id 
            AND b.rn = a.rn - 1 
WHERE b.rn = 1

以下是我使用的示例数据

WITH Commodity as 
(           SELECT 1  as ID , 'Test' as name
 UNION ALL  SELECT 2, 'SecondTest'),
CommodityPrice as 
(   SELECT 1      as Id      , 1         as CommodityID , 1.00  as Price,    '06/01/2011' as EffectiveDate
    UNION ALL SELECT  2            ,1,         1.50      ,'07/01/2011'
    UNION ALL SELECT  4            ,2         ,5.00      ,'06/01/2011'
    UNION ALL SELECT  5            ,2         ,10.00     ,'07/01/2011'
UNION ALL SELECT  0            ,1         ,0.66      ,'05/01/2011'
UNION ALL SELECT  3            ,2         ,3.00      ,'05/01/2011'
 ),

产生了这个输出

name       pricechange
---------- ---------------------------------------
Test       0.50
SecondTest 5.00

(2 row(s) affected)

注意:您也可以从AND b.rn = a.rn - 1中删除JOIN并将AND a.rn = 2添加到WHERE

答案 1 :(得分:2)

没有排名功能:

测试数据:

declare @CommodityPrice table(id int identity, CommodityID int, Price money, EffectiveDate date)

insert @CommodityPrice(CommodityID, Price, EffectiveDate) 
    values (1, 0.66, '05/01/2011'), (1, 1, '06/01/2011'), (1, 1.5, '07/01/2011'),
        (2, 3, '05/01/2011'), (2, 5, '06/01/2011'), (2, 10, '07/01/2011')

查询:

select a.CommodityID, c2.Price - c1.Price
from
(
    select c1.CommodityID, MAX(c1.EffectiveDate) [m1], MAX(c2.EffectiveDate) [m2]
    from @CommodityPrice c1
    join @CommodityPrice c2 on c2.CommodityID = c1.CommodityID
        and c2.EffectiveDate > c1.EffectiveDate
        and not exists (
            select 1
            from @CommodityPrice c3
            where c3.EffectiveDate > c1.EffectiveDate and c3.EffectiveDate < c2.EffectiveDate
        )
    group by c1.CommodityID
)a
join @CommodityPrice c1 on c1.CommodityID = a.CommodityID and c1.EffectiveDate = a.m1
join @CommodityPrice c2 on c2.CommodityID = a.CommodityID and c2.EffectiveDate = a.m2