Запрос на выбор строк с минимальным уникальным значением столбца - PullRequest
0 голосов
/ 19 июня 2020

Мне нужно выбрать строку с минимальным значением столбца B для каждой строки столбца A, но она должна отличаться от других значений, которые до сих пор были выбраны для столбца A. Итак, порядок A имеет значение. Кроме того, если B израсходован и ничего не осталось, то более поздние значения для A должны быть NULL или не отображаться в результате.

И A, и B являются числовыми (или отметкой времени). пример:

A   | B | 
----+---+
1   | 3 | 
1   | 5 | 
1   | 6 | 
2   | 3 | 
2   | 5 | 
9   | 3 |
9   | 5 | 

Итак, желаемый результат:

A   | B | 
----+---+
1   | 3 | 
2   | 5 | 

select A, min(B) group by A явно не работает, потому что я не хочу повторения B. Distinct также не работает, потому что строки уже разные. Я не мог нигде найти подобный вопрос. Фактические данные, с которыми я работаю, - это база данных временных рядов по красному смещению, поэтому A и B - это временные метки. CTE будут особенно приветствоваться.

Ответы [ 2 ]

0 голосов
/ 22 июня 2020

Это в основном задача "найти диагональ". Вам нужно знать ранг B внутри A и ранг A внутри всех. Я считаю, что это работает для приведенных данных:

select A, B from (
  select row_number() over (partition by A order by B) as RN,
    dense_rank() over (order by A) as DR.
    A, B
    from <table> )
where RN = DR; 

Для более сложных случаев это решение станет более сложным.

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

select min(A) as A, B from (
  select decode(A <> nvl(min(A) over (order by DRB, DRA rows between unbounded preceding and 1 preceding),-1), true, 'good', 'no good') as Y,
    A, B from (
    select dense_rank() over (partition by B order by A) as DRA,
      dense_rank() over ( order by B) as DRB,
      A, B from <table>
  )
  where DRA <= DRB
)
where Y = 'good'
group by B
order by A, B;
0 голосов
/ 19 июня 2020

Сначала я подумал, что это можно решить с помощью ROW_NUMBER () OVER (ORDER PARTITION BY B DESC), но есть проблема, числа в B не должны повторяться.

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

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