Количество последовательных строк в группировке

#tsql

#tsql

Вопрос:

У меня есть таблица Samples, которая содержит образцы цен на продукты. Обратите внимание на возрастающий порядок дат.

  ---- ------------ ------- ------- ------------- 
|  Id | Product_Id | Price | Status|    Date     |
 ---- ------------ ------- ------- ------------- 
|  1 |          1 |   400 |     0 | 1404656325  |
|  2 |          2 |   300 |     0 | 1404657325  |
|  3 |          3 |   100 |     0 | 1404658325  |
|  4 |          1 |   400 |     0 | 1404659325  |
|  5 |          2 |   300 |     0 | 1404660325  |
|  6 |          3 |   100 |     1 | 1404661325  |
|  7 |          1 |   500 |     1 | 1404662325  |
|  8 |          2 |   500 |     0 | 1404663325  |
|  9 |          3 |   500 |     1 | 1404664325  |
 ---- ------------ ------- ------- ------------- 
  

Меня интересует группировка идентификаторов Product_Id таким образом, чтобы у меня был список уникальных идентификаторов продукта вместе с последней ценой (то есть самой большой датой).

Это в некотором роде классическая проблема с наибольшим числом n на группу, но, кроме того, мне также нужен числовой столбец, который отображает, сколько последовательных строк в столбце статуса было одинаковым, начиная с самой старой даты.

Итак, учитывая мой пример таблицы выше, я должен в конечном итоге иметь

  ------------ ------- ----------------- 
| Product_Id | Price | SameStatus      |
 ------------ ------- ----------------- 
|          1 |   500 |               1 |
|          2 |   500 |               3 |
|          3 |   500 |               2 |
 ------------ ------- ----------------- 
  

Я надеюсь, что вам ясно, чего я хочу достичь, и есть дружелюбный человек, готовый направлять меня.

Ответ №1:

Это должно сработать. Подход использует ROW_NUMBER()

 ;WITH Samples (Id, Product_Id, Price, [Status], [Date]) AS 
(
    SELECT 1, 1, 400, 0, 1404656325 UNION ALL
    SELECT 2, 2, 300, 0, 1404657325 UNION ALL
    SELECT 3, 3, 100, 0, 1404658325 UNION ALL
    SELECT 4, 1, 400, 0, 1404659325 UNION ALL
    SELECT 5, 2, 300, 0, 1404660325 UNION ALL
    SELECT 6, 3, 100, 1, 1404661325 UNION ALL
    SELECT 7, 1, 500, 1, 1404662325 UNION ALL
    SELECT 8, 2, 500, 0, 1404663325 UNION ALL
    SELECT 9, 3, 500, 1, 1404664325 
)
,NumberingLogic AS
(
    SELECT   *
            ,SameStatus = ROW_NUMBER() OVER (PARTITION BY Product_Id, [Status] ORDER BY [Date])
            ,MaxPrice   = ROW_NUMBER() OVER (PARTITION BY Product_Id ORDER BY [Date] DESC)
    FROM Samples
)
SELECT   Product_Id
        ,Price
        ,SameStatus
FROM NumberingLogic 
WHERE MaxPrice = 1
  

PS.
Как работают ваши даты, мне немного непонятно, но я использовал их для упорядочивания по

Комментарии:

1. Большое вам спасибо. Даты — это просто временные метки unix для простоты, а не то, как я храню их в db на самом деле.