Как мне запросить sql для получения последней версии записи за ту же дату

#sql

#sql

Вопрос:

Я пытаюсь выполнить запрос, который возвращает значение последней опубликованной версии. Версии могут быть названы V1, V2, R1_V1, R1_V2, R2_V1, R2_V2 и опубликованы в этом порядке. Первым сообщением всегда будет #null. Не все версии зависят, я имею в виду, что первая версия дня может быть зарегистрирована как R1_V1 без предварительной публикации V1 и V2.

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

Вот краткий пример:

пример

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

1. Итак, в чем ваш вопрос? Какую СУБД вы действительно используете?

Ответ №1:

В следующий раз вставьте входные данные в виде текста в свой вопрос. Мне пришлось вручную все перепечатать….

Вам нужно дополнительное значение сортировки в дополнение к версии; затем вам нужно добавить значение фильтра на основе порядка сортировки. Используйте функцию OLAP.

 WITH
-- your input ... not part of the final query
indata(dt,ver,val) AS (
            SELECT DATE '2020-02-01',NULL   ,1.1
  UNION ALL SELECT DATE '2020-02-01','V1'   ,1
  UNION ALL SELECT DATE '2020-02-01','R1_V1',1.5
  UNION ALL SELECT DATE '2020-02-02',NULL   ,1.2
  UNION ALL SELECT DATE '2020-02-03',NULL   ,1.3
  UNION ALL SELECT DATE '2020-02-03','V1'   ,1.5
  UNION ALL SELECT DATE '2020-02-03','R1_V1',1.2
  UNION ALL SELECT DATE '2020-02-03','R1_V2',1.3
)
-- end of your input, query starts below, replace ',' with 'WITH' ...
,
-- add a sorting integer. 0 if "ver" is NULL, 1 if it's 'V1', 2 otherwise
w_sort AS (
  SELECT
    *
  , CASE 
      WHEN ver IS NULL THEN 0
      WHEN ver = 'V1'  THEN 1
      ELSE                  2
    END AS srt
  FROM indata
)
,
-- add a filtering integer that is at 1 with the max order value
-- on the sorting criteria, so sort descending
w_fltr AS (
  SELECT
    *
  , ROW_NUMBER() OVER(PARTITION BY dt ORDER BY srt DESC, ver DESC) AS fl
  FROM w_sort
)
-- finally filter by the filter value created above, at 1
SELECT 
  dt
, ver
, val
FROM w_fltr
WHERE fl=1;
-- out      dt     |  ver  | val 
-- out ------------ ------- -----
-- out  2020-02-01 | R1_V1 | 1.5
-- out  2020-02-02 |       | 1.2
-- out  2020-02-03 | R1_V2 | 1.3
  

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

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

Ответ №2:

Вы можете использовать оконные функции:

 select t.*
from (select t.*,
             row_number() over (partition by date
                                order by (case when version not like '%_%' then 1 else 2 end) desc,
                                         version desc
                               ) as seqnum
      from t
     ) t
where seqnum = 1;