выберите, где участник принадлежит только одному клиенту

0

У меня возникли проблемы с поиском запроса. У меня три таблицы

messages
---------------
message_id
phone_num
body
received_time

subscribers
---------------
phone_num
keyword_id

keywords
---------------
keyword_id
client_id

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

Например, для поиска последних сообщений от подписчиков, которые принадлежат только клиенту 1, с данными:

message_id      phone_num   body         received_time
1               111         hi           123456
2               222         test         123489
3               333         msg          213445

phone_num   keyword_id
111         1
111         2
222         3
333         4
333         5

keyword_id      client_id
1               1
2               1
3               1
4               1
5               4

Я хотел бы получить:

message_id   phone_num   body   received_time
2            222         test   123489
1            111         hi     123456

Так как числа 111 и 222 принадлежат только одному клиенту

Имеют смысл? Я не могу понять. Благодаря

  • 0
    Я вижу взаимосвязь между ПОДПИСЧИКАМИ и КЛЮЧЕВЫМИ СЛОВАМИ, но нет связи между СООБЩЕНИЯМИ и двумя другими таблицами.
  • 0
    Столбец phone_num, видимо.
Показать ещё 1 комментарий
Теги:

3 ответа

0
Лучший ответ

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

SELECT DISTINCT m.message_id AS unique_id, m.phone_num, m.body, m.system_time
FROM messages m
JOIN subscribers s ON m.phone_num = s.phone_num
JOIN keywords k ON s.keyword_id = k.keyword_id
WHERE m.phone_num NOT
   IN (
      SELECT s.phone_num
      FROM subscribers s, keywords k
      WHERE k.client_id != 'XXXX'
      AND k.keyword_id = s.keyword_id
  )
ORDER BY m.system_time DESC

Спасибо за помощь, и если кто-то может улучшить мой запрос, сделайте это!

0

Я построил этот сложный запрос:

SELECT
  m.message_id, m.phone_num, m.body, m.received_time

FROM
  messages m

WHERE m.phone_num IN (
  SELECT 
    phone_num 
  FROM 
    subscribers s,
    keywords k
  WHERE 
    s.keyword_id = k.keyword_id AND
    k.client_id = 1 AND
    s.phone_num IN (
      SELECT 
        s.phone_num
      FROM 
        subscribers s, keywords k
      WHERE
        s.keyword_id = k.keyword_id
      GROUP BY s.phone_num
      HAVING COUNT(DISTINCT k.client_id) = 1
    )
)

Самый внутренний подзапрос извлекает "уникальные" номера, например. числа, которые принадлежат только одному клиенту.

Среднее внутреннее подзапрос извлекает среди этих чисел только те, которые принадлежат желаемому клиенту (обратите внимание на k.client_id = 1).

И, наконец, внешний запрос извлекает сообщения, номера которых можно найти в этом списке телефонов.

Примечание о производительности: средний подзапрос в порядке, если вы поместите индекс в поле client_id. Самый внутренний запрос немного проблематичен, так как он анализирует все строки таблицы ключевых слов. Как насчет size/number_of_rows в ваших таблицах?

Надеюсь, это поможет вам.

0

В базе данных с идентичными макетными данными этот запрос работал у меня. Вероятно, это будет не так быстро, но он выполнит свою работу.

SELECT m.* FROM messages m

WHERE m.phone_num IN (
    SELECT DISTINCT s.phone_num FROM subscribers s, keywords k

    WHERE s.keyword_id = k.keyword_id
      AND k.client_id = ???
      AND NOT EXISTS (
          SELECT ki.client_id FROM keywords ki, subscribers si

          WHERE ki.keyword_id = si.keyword_id
            AND si.phone_num = s.phone_num
            AND ki.client_id <> k.client_id
          )
)
  • 0
    Спасибо, но как я могу получить сообщения для конкретного клиента? Например, я хочу, чтобы все сообщения клиенту 23 были от подписчиков, которые принадлежат только клиенту 23.
  • 0
    Я добавил это предложение в запрос. Просто подставить ??? с идентификатором клиента, который вас интересует.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню