Запрос SQL Server - ведение первой и последней уникальных записей группы - PullRequest
0 голосов
/ 20 февраля 2019

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

Ежедневные вставки:

  1. данные ежедневно импортируются в таблицы, которые постоянно обновляют статус продуктов
  2. ежедневные обновления статуса сообщают нам, когда продукты были перечислены, перечислены ли они в настоящее время, а затем в последнюю дату, когда они были перечислены
  3. по истечении {X} времени, мы можем нормализовать данные

Очистка и ранжирование:

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

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

Образец данных:

enter image description here Я обнаружил, что фотография - это самый простой способ показать данные, показать, что нужно и не нужно - я надеюсь, что это облегчает и не делает их тупыми.

В примерах данных:

  • "ridgerapp", мы хотим сохранить записи для 03/12/17 и 06/12/17.
  • "ridgerapp", мы хотим удалить записи, которые попадают между датами выше.
  • "ridgerapp", мы также хотим установить / обновить записи за 12/12/17 и 06/12/17 как первое и последнее вхождение - что-то вроде -
  • обновить набор таблиц 03/ 12/17 = 0 (первый), 06/12/17 = 1 (последний)

  • "sierra" - это просто еще одна расширенная выборка данных, и мы хотим сохранить записи для12/06/16 и 12/11/16.

  • "Сьерра" удаляет записи, которые попадают между 12/06/16 и 12/11/16.
  • "Сьерра"обновить статус / ранг для записей 12/06/16 и 12/11/16 как первое и последнее вхождение.
  • обновить набор таблиц 12/06/16 = 0 (первый), 12/11/ 16 = 1 (последний).

Вывод:

Использование псевдокода - это общая цель:

  • выбор отдельных записей в таблице (используя идентификатор, имя, цвет, значение в качестве уникальных идентификаторов)
  • для records в каждой группе просматривают историю и находят верхнюю и нижнюю даты
  • удаляют записи между верхними и нижними датами для каждой группы
  • обновляют историю со статусом / рангом (имя поля - ранг) 0 и 1 для значений в каждой группе
  • с использованием данных выборки, результаты будут в итоге

Обновленные значения таблицы:

 23  ridgerapp  blue    25  03/12/17    0
 23  ridgerapp  blue    25  06/12/17    1
 57  sierra     red     15  12/06/16    0
 57  sierra     red     15  12/11/16    1

1 Ответ

0 голосов
/ 20 февраля 2019

Я бы использовал CTE с оконной функцией row_number(), чтобы найти первую и последнюю строки для каждой группы , а затем обновить ее.

Вы не сделалиукажите, что делает группу группу , поэтому я основываю это только на ID.Если вы хотите, чтобы группа была набором столбцов, например ID и Color и Value, просто добавьте эти столбцы в список partition by.Для выборочных данных результат будет одинаковым, но разные выборочные данные будут иметь разные результаты.

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

declare @table table (id int, [name] varchar(64), color varchar(16), [value] int, history date)
insert into @table
values
(23,'ridgerapp','blue',25,'20170312'),
(23,'ridgerapp','blue',25,'20170325'),
(23,'ridgerapp','blue',25,'20170410'),
(23,'ridgerapp','blue',25,'20170610'),
(23,'ridgerapp','blue',25,'20170612'),

(57,'sierra','red',15,'20161206'),
(57,'sierra','red',15,'20161208'),
(57,'sierra','red',15,'20161210'),
(57,'sierra','red',15,'20161210')   --notice this is a duplicate row

;with cte as(
select 
    *
    ,fst = row_number() over (partition by id order by history asc)
    ,lst = row_number() over (partition by id order by history desc)
from @table
)

delete from cte
where fst !=1 and lst !=1

select 
    *
    ,flag = case when row_number() over (partition by id order by history asc) = 1 then 0 else 1 end
from @table

ВОЗВРАТ

+----+-----------+-------+-------+------------+------+
| id |   name    | color | value |  history   | flag |
+----+-----------+-------+-------+------------+------+
| 23 | ridgerapp | blue  |    25 | 2017-03-12 |    0 |
| 23 | ridgerapp | blue  |    25 | 2017-06-12 |    1 |
| 57 | sierra    | red   |    15 | 2016-12-06 |    0 |
| 57 | sierra    | red   |    15 | 2016-12-10 |    1 |
+----+-----------+-------+-------+------------+------+
...