Путать с запросом SQL - PullRequest
       5

Путать с запросом SQL

0 голосов
/ 02 мая 2019

Предположим, у нас есть база данных для приложения чата:

CREATE TABLE Users (uid int PRIMARY KEY, name text, phone text );

CREATE TABLE Messages (recipient int REFERENCES Users(uid), sender int 
REFERENCES Users(uid), time timestamp NOT NULL, message text NOT NULL, 
PRIMARY KEY (recipient, sender, time));

Я хочу найти все сообщения, которые были отправлены как минимум между двумя разными парами пользователей. Например, если сообщение «Привет» было отправлено от пользователя 1 пользователю 2 и от пользователя 75 к пользователю 83, а затем он должен быть показан результату. Однако, если он был отправлен только между Пользователем 1 и Пользователем 2, он не должен отображаться в результате.

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

SELECT message 
FROM Messages 
GROUP BY message 
HAVING COUNT(*) > 1

Однако это не поможет, поскольку одна и та же пара пользователей могла отправлять одно и то же сообщение снова и снова. Можно ли группировать по отправителю, получателю и сообщению одновременно? Если да, что это даст мне в результате?

Кроме того, есть ли способ, которым я мог бы легко заполнить эти две таблицы случайными значениями и отработать запросы самостоятельно, чтобы проверить их?

Заранее спасибо!

Ответы [ 4 ]

2 голосов
/ 02 мая 2019

Это будет работать для MySql:

SELECT message 
FROM Messages 
GROUP BY message 
HAVING 
  COUNT(distinct least(recipient, sender), greatest(recipient, sender)) > 1

См. Демоверсию .

1 голос
/ 06 мая 2019

Самый простой способ добиться этого - использовать следующий запрос:

select message, count(*)
from Messages
group by message
HAVING COUNT(distinct least(recipient, sender), greatest(recipient, sender)) > 1

Это улучшает запрос forpas, добавляя количество раз, когда это сообщение использовалось.

1 голос
/ 02 мая 2019

Да, сначала начните с группировки user1, user2 и сообщения.Это дает вам уникальное сообщение для каждой пары:

SELECT case when recipient > sender then recipient else sender end user1,
       case when recipient > sender then sender else recipient end user2,
       message 
FROM Messages 
GROUP BY user1, user2, message

Затем из этой группы результатов по сообщению и возвращают только счетчик больше 1. Вы можете использовать вложенный запрос, чтобы сделать это:

SELECT message, COUNT(message) 
FROM (SELECT case when recipient > sender then recipient else sender end user1,
            case when recipient > sender then sender else recipient end user2,
            message 
     FROM Messages 
     GROUP BY user1, user2, message) PairMessages 
GROUP BY message 
HAVING COUNT(message) > 1

Возможно, начните с этого теста:

INSERT INTO Users VALUES (1,'john',1111111111)
INSERT INTO Users VALUES (2,'paul',2222222222)
INSERT INTO Users VALUES (75,'george',7575757575)
INSERT INTO Users VALUES (83,'ringo',8383838383)
INSERT INTO Messages VALUES (2,1,GETDATE(),'Yesterday')
INSERT INTO Messages VALUES (1,2,GETDATE(),'hello')
INSERT INTO Messages VALUES (75,83,GETDATE(),'yellow')
INSERT INTO Messages VALUES (75,83,GETDATE(),'hello')

Вы сможете получить привет, поскольку ваше сообщение отправлено между более чем одной парой пользователей.

Редактировать: я обновилвыше с правильным ответом, чтобы показать, что каждая пара пользователей уникальна для каждого сообщения.Также может быть хорошей идеей создать groupID для каждой пары пользователей.Затем вы можете добавить столько пользователей, сколько хотите к этому groupID.Смотрите здесь для идеи: http://sqlfiddle.com/#!9/fbc2e2/3

0 голосов
/ 02 мая 2019

Вы можете использовать EXISTS для фильтрации:

SELECT m.message 
FROM Messages m
WHERE EXISTS (SELECT 1
              FROM Messages m2
              WHERE m2.message = m.message AND
                    m2.recipient NOT IN (m.recipient, m.sender) AND
                    m2.sender NOT IN (m.recipient, m.sender)
             )       
GROUP BY m.message ;

EXISTS проверяет, что другая строка с тем же сообщением имеет другую пару пользователей.

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