SQL группа без агрегации - PullRequest
1 голос
/ 18 апреля 2019

Я использую PostgreSQL, и у меня есть следующая таблица (упрощенная для вопроса):

CREATE TABLE SMSNotification (
    enduser int,
    message int,
    FOREIGN KEY (enduser) REFERENCES EndUser (id),
    FOREIGN KEY (message) REFERENCES Message (id)
);

Теперь я хочу отправить сообщения в пакетном режиме. Поэтому я бы хотел сгруппировать уведомления по сообщениям. Проблема в том, что оператор GROUP BY в SQL агрегирует строки. Поэтому я не могу получить список конечных пользователей в каждой группе:

SELECT enduser, message from SMSNotification GROUP BY message; /* Doesn't work */

Я подумал о решении этой проблемы, сначала получив список всех отдельных сообщений:

SELECT DISTINCT message FROM SMSNotification;

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

 SELECT enduser FROM SMSNotification WHERE message = current_message;

Однако это кажется неэффективным из-за того, что N + 1 выбирает . Есть ли лучшее решение?


Пример: Рассмотрим следующую таблицу:

+---------+---------+
| enduser | message |
+---------+---------+
| 1       | 1       |
| 2       | 1       |
| 3       | 1       |
| 1       | 2       |
| 2       | 2       |
| 1       | 3       |
| 3       | 3       |
+---------+---------+

В идеале я хотел бы получить список таблиц в качестве вывода:

+---------+---------+
| enduser | message |
+---------+---------+
| 1       | 1       |
| 2       | 1       |
| 3       | 1       |
+---------+---------+

+---------+---------+
| enduser | message |
+---------+---------+
| 1       | 2       |
| 2       | 2       |
+---------+---------+

+---------+---------+
| enduser | message |
+---------+---------+
| 1       | 3       |
| 3       | 3       |
+---------+---------+

Однако, если я правильно понимаю, вы не можете получить список таблиц в качестве вывода из запроса SQL.

Ответы [ 2 ]

2 голосов
/ 18 апреля 2019

Вы можете объединить пользователей в массив, как в

SELECT array_agg(enduser) AS endusers, message
FROM SMSNotification
GROUP BY message;

 endusers | message 
----------+---------
 {3}      |       3
 {2,3}    |       2
 {1,3}    |       1
(3 rows)
1 голос
/ 18 апреля 2019

Я думаю, что вы ищете команду partition by (оконная функция):

select row_number() over (partition by message order by enduser)
    as rn
    , message
    , enduser
from SMSNotification

A group by уменьшает количество возвращаемых строк, агрегируя несгруппированные столбцы, тогда как partition by не влияет на количество строк, он просто указывает, как вывод должен быть отображен или рассчитан.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...