Как сгруппировать значения подсчета в диапазоны, такие как ровно один, от 2 до 5, более 5

#sql #sql-server #group-by #range

Вопрос:

У меня есть таблица транзакций с концепцией отправителя и получателя, которые могут отправлять транзакции:

Таблица транзакций с данными

Теперь я хочу получить результирующий набор, который должен включать диапазон количества уникальных отправителей на одного получателя:

  • один получатель получает от 1 отправителя
  • один получатель получает от 2-5 отправителей
  • один получатель получает от 6-10 отправителей
  • один получатель получает от 11-20 отправителей
  • один получатель получает более 20 отправителей

Требуется окончательное отображение данных из таблицы транзакций

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

Комментарии:

1. Вы можете использовать выбрать получателя, количество(отдельный отправитель) …. Пожалуйста, обратите внимание, что изображения не очень полезны, и вы должны предоставить хорошие образцы в виде текста и желаемого результата.

2. @CetinBasoz как я получу получателя, у которого только один отправитель? Если я смогу понять это, у других quries будет похожая картина.

3. Я удалил здесь различные теги версий (одна из которых-версия, которая не поддерживалась более 2 лет). Пометка версии, которую вы используете, полезна, но я сомневаюсь , что вы используете все 3 из них одновременно.

Ответ №1:

Это был бы беспорядок в качестве комментария. Вы на самом деле не предоставили примерные данные и желаемые выходные данные для начала (я не принимаю фотографии в качестве образца). В любом случае, то, что вы описываете, — это простой подсчет():

 select receiver, count(distinct sender) senderCount from myTable group by receiver order by count(distinct sender);  

сделал бы это. Разложение результата по ведрам, таким как 1, 2-5, … может быть сделано по-разному. т. е.:

 with counts(receiver, senderCount) as (  select receiver, count(distinct sender)  from myTable  group by receiver ) select receiver,  case   when senderCount = 1 then '1'  when senderCount gt; 1 and senderCount lt;= 5 then '2-5'  when senderCount gt; 5 and senderCount lt;= 10 then '6-10'  when senderCount gt; 10 and senderCount lt;= 20 then '11-20'  when senderCount gt; 20 then 'Over 20'  end as individualGroup from counts;   

Комментарии:

1. Вам также нужно сгруппироваться по тому же case выражению

2. @SalmanA, о каком падежном выражении вы говорите? Я не вижу такого столбца (в любом случае я не вижу структуры таблицы, кроме вычета из первого рисунка).

3. Он вернет такие данные, как 1, 2-5, 2-5, 11-20 (4 строки), и OP хочет, чтобы они были агрегированы 1: 1, 2-5: 2, 11-20: 1 (3 строки)

4. @SalmanA, ты уверен в этом? Где это указано?

5. Большое спасибо @CetinBasoz, изучив обсуждение вашего ответа, я понял идею и решил проблему. Извините, что не объяснил это должным образом

Ответ №2:

Создайте (виртуальную) таблицу, в которой хранятся диапазоны, а затем соедините ее с совокупными данными:

 SELECT ranges.*, COUNT(*) AS ReceiversInRange --, other aggregates FROM (VALUES  (1, 1, 1, 'Low risk'),  (2, 2, 5, 'Low risk'),  (3, 6, 10, 'Medium risk'),  (4, 11, 20, 'Medium-high'),  (5, 20, NULL, 'High risk') ) AS ranges(id, lb, ub, label) INNER JOIN (  SELECT COUNT(DISTINCT Sender) AS SenderCount --, other aggregates  FROM t  GROUP BY Receiver  ) AS aggdata ON SenderCount gt;= lb AND (SenderCount lt;= ub OR ub IS NULL) GROUP BY id, lb, ub, label