SQL запрос для выбора до N записей по критериям - PullRequest
2 голосов
/ 09 марта 2020

Мне было интересно, можно ли использовать SQL (предпочтительно снежинку), чтобы выбрать до N записей с учетом определенных критериев. Для иллюстрации: допустим, у меня есть таблица с 1 миллионом записей, содержащая полные имена и телефонные номера.

Нет ограничений на количество телефонных номеров, которые могут быть назначены X человеку, но я хочу выбрать только до 10 номеров на человека, даже если у человека больше 10.

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

Можно ли это сделать?

Ответы [ 2 ]

4 голосов
/ 09 марта 2020

Вы можете использовать оконные функции для решения этой задачи с наибольшим числом групп:

select t.*
from (
    select 
        t.*, 
        row_number() over(partition by name order by phone_number) rn
    from mytable t
) t
where rn <= 10

Обратите внимание, что вам нужен столбец порядка, чтобы определить, что на самом деле означает «10 лучших». Я предположил phone_number, но вы можете изменить его на тот, который лучше всего подходит для вашего варианта использования.

Еще лучше: как прокомментировал waldente, снежинка имеет синтаксис qualify, что устраняет необходимость в подзапросе:

select t.*
from mytable t
qualify row_number() over(partition by name order by phone_number) <= 10
2 голосов
/ 09 марта 2020

Этот запрос поможет вашему требованию:

select 
	full_name,
	phonenumber 
from 
	(select 
		full_name, 
		phonenumber, 
		ROW_NUMBER() over (partition by phonenumber order by  full_name desc) as ROW_NUMBER from sample_tab) a 
where 
	a.row_number between 1 and 10 
order by 
	full_name asc,
	phonenumber desc;

с использованием функции Snowflake Qualify:

select 
	full_name, 
	phonenumber 
from 
	sample_tab qualify row_number() over (partition by phonenumber order by full_name) between 1 and 10 
order by 
	full_name asc ,
	phonenumber desc;
...