SQL Server 2008:计算日期和价格变化

时间:2017-05-12 18:37:38

标签: sql-server tsql

我有一个包含3列的SQL Server 2008表:art_iddateprice。价格不时变化。日期不是连续的。

如何计算每个art_id的价格变化以及变化的数量?

2 个答案:

答案 0 :(得分:1)

使用MIN()

的自我加入
select
    t.art_id,
    ,t.date
    ,t.price
from
    yourTable t
    inner join
    (select art_id, price, min(date) dt
    from yourTable
    group by art_id, price) t2 on t2.dt = t.date and t2.art_id = t.art_id and t2.price = t.price

然后,使用此结果集,您可以使用LEADLAG计算价格变化(如果您在2012年以上)或使用带有ROW_NUMBER()的窗口函数CTE 。如果需要更多说明,请指定您所使用的版本。

答案 1 :(得分:1)

类似的东西:

DECLARE @artSales TABLE (artid int, dt date, price money);

INSERT @artSales
VALUES 
(1, '20170102', 10), (1, '20170108', 10), (1, '20170112', 8.50), (1, '20170115', 8.50),
(2, '20170102', 20), (2, '20170109', 20), (2, '20170112', 35), (2, '20170116', 40),
(3, '20170101', 500), (3, '20170111', 500), (3, '20170130', 500);

SELECT 
  artid,
  dt,
  oldPrice = price,
  PriceChange =
  CASE 
    LAG(price, 1, price) OVER (PARTITION BY artid ORDER BY dt) 
    WHEN price THEN 0 ELSE 1
  END,
  NewPrice = LAG(price, 1, price) OVER (PARTITION BY artid ORDER BY dt)
FROM @artSales;

结果:

artid       dt         oldPrice              PriceChange NewPrice
----------- ---------- --------------------- ----------- ---------------------
1           2017-01-02 10.00                 0           10.00
1           2017-01-08 10.00                 0           10.00
1           2017-01-12 8.50                  1           10.00
1           2017-01-15 8.50                  0           8.50
2           2017-01-02 20.00                 0           20.00
2           2017-01-09 20.00                 0           20.00
2           2017-01-12 35.00                 1           20.00
2           2017-01-16 40.00                 1           35.00
3           2017-01-01 500.00                0           500.00
3           2017-01-11 500.00                0           500.00
3           2017-01-30 500.00                0           500.00

更新 - 适用于2012年之前的系统:

WITH prev AS
(
  SELECT rn = ROW_NUMBER() OVER (PARTITION BY artid ORDER BY dt), *
  FROM @artSales
)
SELECT 
  as1.artid,
  as1.dt,
  OldPrice    = as1.price,
  PriceChange = CASE WHEN as1.price <> as2.price THEN 1 ELSE 0 END,
  NewPrice    = ISNULL(as2.price, as1.price)
FROM prev as1
LEFT JOIN prev as2 ON as1.artid = as2.artid AND as1.rn = as2.rn+1;