SQL-накопление последних ненулевых значений столбцов

#sql #group-by #sybase #sqlanywhere #rollup

#sql #группировать по #sybase #sqlanywhere #сводная

Вопрос:

У меня есть таблица SQLAnywhere, подобная этой:

 id        int         not null,
inserted  datetime    not null,
modified  datetime    not null,
data1     varchar(20)     null
data2     varchar(20)     null
  

Разработчик не поместил уникальный индекс в идентификатор, и теперь есть куча строк с одинаковым идентификатором, но разными значениями для data1 и data2 по строкам, включая некоторые нули. Мне нужно исправить это, свернув все строки с одинаковым идентификатором в отдельные строки в новой таблице, используя самое раннее вставленное время, время последнего изменения и последние (по измененному времени) ненулевые значения data1 и data2 (если только все строки для этого идентификатора не имеют null,в этом случае значение свернутой строки будет равно нулю). Я не могу просто использовать последнюю строку; Мне нужно последнее ненулевое значение для каждого отдельного столбца.

Итак, три строки, подобные этой:

 1, '2016-01-01', '2016-01-02', 'first', null
1, '2016-01-05', '2016-01-07', null, 'second'
1, '2016-01-10', '2016-01-12', 'third', null
  

… будет свернуто до:

 1, '2016-01-01', 2016-01-12', 'third', 'second'
  

Я рассмотрел неэквивалентные самосоединения и оконные функции, но я не могу заставить их свернуть это последнее ненулевое значение для отдельных столбцов. Есть ли классный SQL-способ сделать это в одном запросе или я, черт возьми, пишу для этого Java-программу?

Спасибо

Ответ №1:

Я бы использовал LAST_VALUE .

 select
  id
  ,min(inserted) over (partition by id)
  ,max(modified) over (partition by id)
  ,last_value(data1 ignore nulls) over (partition by id order by modified)
  ,last_value(data2 ignore nulls) over (partition by id order by modified)
from
  table_a
  

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

1. Отлично! Спасибо, Джереми.