У меня возникли проблемы с поиском запроса. У меня три таблицы
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 принадлежат только одному клиенту
Имеют смысл? Я не могу понять. Благодаря
Ни один из ваших запросов не будет работать для меня, они заморозили сервер. Не знаю, почему, возможно, плохое индексирование. Но я выяснил, что запрос выполняется довольно быстро
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
Спасибо за помощь, и если кто-то может улучшить мой запрос, сделайте это!
Я построил этот сложный запрос:
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 в ваших таблицах?
Надеюсь, это поможет вам.
В базе данных с идентичными макетными данными этот запрос работал у меня. Вероятно, это будет не так быстро, но он выполнит свою работу.
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
)
)
???
с идентификатором клиента, который вас интересует.