Разница в последней и второй последней цене - PullRequest
1 голос
/ 12 июля 2011

У меня есть две таблицы следующим образом:

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 ]

2 голосов
/ 12 июля 2011

Без функций ранжирования:

Тестовые данные:

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
2 голосов
/ 12 июля 2011

Предполагается, что SQL 2005 или более поздняя версия.Просто используйте ROW NUMBER , чтобы присвоить номера строкам, а затем JOIN 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...