Я хотел бы подсчитать всех клиентов и вернуть дату регистрации для третьего клиента, который подписался.
По существу оцените количество клиентов, которые зарегистрировались, и как только количество зарегистрированных клиентов достигнет 3, чтобы вернуть дату регистрации и идентификатор 3-го клиента.
образец таблицы
customer_id signup_date
3993 2019-01-01
9392 2019-01-02
2143 2019-01-03
8372 2019-01-04
выходная таблица
customer_id signup_date
2143 2019-01-03
Используйте row_number()
для фильтрации нужного значения:
row_number()
→ bigint
Returns a unique, sequential number for each row, starting with one, according to the ordering of rows within the window partition.
-- sample data
WITH dataset (customer_id, signup_date ) AS (
VALUES (3993, date '2019-01-01'),
(9392, date '2019-01-02'),
(2143, date '2019-01-03'),
(8372, date '2019-01-04')
)
--query
select customer_id, signup_date
from (
select *,
row_number() over(order by signup_date) rn
from dataset
)
where rn = 3
Выход:
Пользовательский ИД | signup_date |
---|---|
2143 | 2019-01-03 |
Обратите внимание, что в случае совпадения дат (т. е. нескольких строк с одинаковой датой) возвращаемое значение не определено, поэтому вам нужно будет применить дополнительный порядок (например, по идентификатору — row_number() over(order by signup_date, customer_id) rn
) (или, возможно, рассмотреть возможность использования комбинации rank
и row_number
для возврата нескольких полученные результаты)
select * from (
select
customer_id,
signup_date,
rank() over (order by signup_date)
from signups
) sub where sub.rank = 3;
customer_id | signup_date | rank
-------------+-------------+------
2143 | 2019-01-03 | 3
(1 row)
Вы могли бы использовать
select customer_id, signup_date
from SampleTable
order by signup_date
offset 2
fetch next 1 rows
Вы можете использовать что-то вроде этого:
SELECT customer_id, signup_date
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY signup_date) AS row_num
, customer_id
, signup_date
FROM your_table
) -- AS sub
WHERE row_num = 3
Дата регистрации всегда в порядке возрастания? Как правило, когда в таблице много строк, функция Rank() будет работать лучше. Rank() быстрее, чем Row_Number(). Я бы посоветовал использовать подзапросы только тогда, когда вам нужно быстро получить результаты. Если запрос нужно использовать каждый день, повторно использовать, попробуйте использовать CTE для лучшей читабельности и производительности.
With CTE_Customer_Signup_Date AS (
SELECT Rank() OVER (ORDER BY signup_date) AS Rank
, customer_id
, signup_date
FROM your_table
)
Select customer_id, signup_date from CTE_Customer_Signup_Date
where Rank =3