选择成员仅属于一个客户的位置

时间:2010-11-16 05:42:27

标签: mysql

我无法搞清楚查询。我有三张桌子

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仅属于一个客户

有意义吗?我无法弄清楚。感谢

3 个答案:

答案 0 :(得分: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
          )
)

答案 1 :(得分: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怎么样?

希望它会对你有所帮助。

答案 2 :(得分: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

感谢您的帮助,如果有人可以改进我的查询,请执行!