Как выбрать строки, в которых значения были изменены для идентификатора - PullRequest
1 голос
/ 11 февраля 2020

У меня есть таблица, которая выглядит следующим образом

id         effective_date    number_of_int_customers
123        10/01/19            0
123        02/01/20            3
456        10/01/19            6
456        02/01/20            6
789        10/01/19            5
789        02/01/20            4
999        10/01/19            0
999        02/01/20            1

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

Результат, который я ищу, следующий:

id         effective_date    number_of_int_customers
123        02/01/20            3 
999        02/01/20            1

Результат вернул бы только тех продавцов, у которых изначально было 0 международных клиентов, а теперь есть хотя бы 1. Я видел подобные сообщения здесь которые используют вложенные запросы для извлечения записей, где первая и последняя дата имеют разные значения. Но я хочу только получить записи, где исходное значение было 0. Есть ли способ сделать это в одном запросе в SQL?

1 Ответ

0 голосов
/ 11 февраля 2020

В вашем случае подойдет простое агрегирование - при условии, что 0 является самым ранним значением:

select id, max(number_of_int_customers)
from t
where effective_date in ('2019-10-01', '2020-02-01')
group by id
having min(number_of_int_customers) = 0;

Очевидно, что это неверно, если значения могут уменьшиться до нуля. Но это предложение having решает эту проблему:

having min(case when number_of_int_customers = 0 then effective_date end) = min(effective_date)

Альтернативой является использование оконных функций, таких как first_value():

select distinct id, last_noic
from (select t.*,
             first_value(number_of_int_customers) over (partition by id order by effective_date) as first_noic,
             first_value(number_of_int_customers) over (partition by id order by effective_date desc) as last_noic,
      from t
      where effective_date in ('2019-10-01', '2020-02-01')
     ) t
where first_noic = 0;

Хммм, если подумать, мне нравится lag() лучше:

select id, number_of_int_customers
from (select t.*,
             lag(number_of_int_customers) over (partition by id order by effective_date) as prev_noic
      from t
      where effective_date in ('2019-10-01', '2020-02-01')
     ) t
where prev_noic = 0;
...