Ниже решение будет более портативным, чем DISTINCT ON
, что является специфичным для Postgres. Используйте row_number()
для перечисления строк и получить все различные клиентов (идентифицированный по электронной почте), которые имеют свою первую сумму сделки больше, чем 500.
Edit: Я включал три пути для достижения того же результата. Выберите то, что вы предпочитаете.
Первый подход - использование row_number()
select
distinct email
from (
select
email,
amount,
row_number() OVER (PARTITION BY email ORDER BY transaction_time) AS rn
from <derived_table_here>
) t
where
rn = 1
and amount > 500
Второй подход - использование DISTINCT ON
select
email
from (
select distinct on (email)
email,
amount
from <derived_table_here>
order by email, transaction_time
) t
where amount > 500
Третий подход - использование NOT EXISTS
select
email
from <derived_table_here> t1
where
amount > 500
and not exists(
select 1
from <derived_table_here> t2
where
t1.email = t2.email
and t1.transaction_time > t2.transaction_time
)
Я нахожу третий метод наиболее переносимым, поскольку MySQL, например, не поддерживает функции окна AFAIK. Это просто в случае переключения между базами данных в будущем - меньше работы для вас.
Проверено на образце ниже:
email | transaction_time | amount
-----------------+----------------------------+--------
[email protected] | 2016-09-26 19:01:15.297251 | 400 -- 1st, amount < 500
[email protected] | 2016-09-26 19:01:19.160095 | 500
[email protected] | 2016-09-26 19:01:21.526307 | 550
[email protected] | 2016-09-26 19:01:28.659847 | 600 -- 1st, amount > 500
[email protected] | 2016-09-26 19:01:30.292691 | 200
[email protected] | 2016-09-26 19:01:31.748649 | 300
[email protected] | 2016-09-26 19:01:38.59275 | 200 -- 1st, amount < 500
[email protected] | 2016-09-26 19:01:40.833897 | 100
[email protected] | 2016-09-26 19:01:51.593279 | 501 -- 1st, amount > 500
Можете ли вы добавить пример данных и ожидаемый результат. –