2015-03-14 2 views
1

У меня есть таблица, содержащая данные о цене продукта, как это:Рассчитать скидка между неделями

ProductId RecordDate     Price 
46   2015-01-17 14:35:05.533  112.00 
47   2015-01-17 14:35:05.533  88.00 
45   2015-01-17 14:35:05.533  134.00 

Я был в состоянии группировать данные по неделям и продуктом, с этим запросом:

SET DATEFIRST 1; 

SELECT DATEADD(WEEK, DATEDIFF(WEEK, 0, [RecordDate]), 0) AS [Week], ProductId, MIN([Price]) AS [MinimumPrice] 
FROM [dbo].[ProductPriceHistory] 
GROUP BY DATEADD(WEEK, DATEDIFF(WEEK, 0, [RecordDate]), 0), ProductId 
ORDER BY ProductId, [Week] 

получения этот результат:

Week      Product Price 
2015-01-12 00:00:00.000 1   99.00 
2015-01-19 00:00:00.000 1   98.00 
2015-01-26 00:00:00.000 1   95.00 
2015-02-02 00:00:00.000 1   95.00 
2015-02-09 00:00:00.000 1   95.00 
2015-02-16 00:00:00.000 1   95.00 
2015-02-23 00:00:00.000 1   80.00 
2015-03-02 00:00:00.000 1   97.00 
2015-03-09 00:00:00.000 1   85.00 
2015-01-12 00:00:00.000 2   232.00 
2015-01-19 00:00:00.000 2   233.00 
2015-01-26 00:00:00.000 2   194.00 
2015-02-02 00:00:00.000 2   194.00 
2015-02-09 00:00:00.000 2   199.00 
2015-02-16 00:00:00.000 2   199.00 
2015-02-23 00:00:00.000 2   199.00 
2015-03-02 00:00:00.000 2   214.00 

Теперь для каждого продукта я хотел бы получить разницу между значениями за две недели, поэтому что я могу рассчитать скидку. Я не знаю, как написать это как SQL-запрос!

EDIT: Ожидаемый результат будет что-то вроде этого:

Product Price 
1   -12.00 
2   15.00 

Спасибо!

+0

Вы можете добавить ожидаемый результат –

+0

Какие dbms? (Дата/время является одной из областей, где многие продукты dbms делают что-то по-своему ...) – jarlh

+1

Вы оба правы, я редактировал мой вопрос! СУБД - Sql Server 2014. Спасибо! – Alessandro

ответ

2

Поскольку вы используете Sql Server 2014, вы можете использовать функцию окна LAG или LEAD для этого.

Сгенерируйте Row number, чтобы найти последние две недели с каждым product.

;WITH cte 
    AS (SELECT *, 
       Row_number()OVER(partition BY product ORDER BY weeks DESC)rn 
     FROM Yourtable) 
SELECT product, 
     price 
FROM (SELECT product, 
       Price=price - Lead(price)OVER(partition BY product ORDER BY rn) 
     FROM cte a 
     WHERE a.rn <= 2) A 
WHERE price IS NOT NULL 

Традиционное решение, можно использовать перед Sql server 2012

;WITH cte 
    AS (SELECT *, 
       Row_number()OVER(partition BY product 
        ORDER BY weeks DESC)rn 
     FROM Yourtable) 
SELECT a.Product, 
     b.Price - a.Price 
FROM cte a 
     LEFT JOIN cte b 
       ON a.Product = b.Product 
       AND a.rn = b.rn + 1 
WHERE a.rn <= 2 
     AND b.Product IS NOT NULL 
1

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

;WITH WeeklyPrice 
AS (
    ... your query ... 
), WeeklyPriceWithRowNum 
AS (
    SELECT * 
    FROM (
     SELECT w.ProductId, w.Price, 
      ROW_NUMBER() OVER(PARTITION BY w.ProductId ORDER BY w.Week DESC) AS RowNum 
     FROM WeeklyPrice w 
    ) x 
    WHERE x.RowNum <= 2 
) 
SELECT pvt.ProductId, [1] AS LastPrice, [2] AS SecondLastPrice, [1] - ISNULL([2], 0) AS Diff 
FROM WeeklyPriceWithRowNum wp 
PIVOT(MAX(wp.Price) FOR wp.RowNum IN ([1], [2])) pvt 
Смежные вопросы