试图简化MySQL查询

时间:2013-07-04 12:40:50

标签: php mysql sql

我真的很感激任何试图简化MySQL查询的帮助。查询的目的是从消息表(users_messages)中检索消息,消息表包含以下列:message_id,from_id,to_id,message_content,date_sent。

from_id和to_id需要加入具有以下列的用户表(用户):user_id,user_username。

另外我应该提一下,有一个被阻止的用户表(users_blocked),如果此表中有user_id功能,它会过滤掉任何消息。

所有这一切都很好,消息按照最新的第一个订购,这就是我想要的。我唯一的问题是它没有拉动相应的'message_content'。即它正在拉最近的日期,但不是最近的消息。

也许我需要一种不同的方法(例如子查询),但我无法理解它。

以下是查询:

select m.message_content,
    if(from_id < to_id, concat(from_id,to_id), concat(to_id,from_id)) as ft,
    if (from_id = $my_id, to_id, from_id) as other_id,
    max(date_sent) as most_recent
from users_messages m
    left join users_blocked ub1 on (from_id = ub1.blocked_id and ub1.user_id = $my_id)
    left join users_blocked ub2 on (to_id = ub2.blocked_id and ub2.user_id = $my_id)
where
    (from_id = $my_id or to_id = $my_id)
    and ub1.blocked_id is null
    and ub2.blocked_id is null
group by
    ft
order by
    most_recent desc

对不起,这是表结构:

用户

user_id    user_username
1          Simon
2          Amber
3          Tom

users_messages

message_id    from_id    to_id    date_sent             message_content
1             1          2        2012-07-04 11:52:12   Hello
2             1          2        2012-07-04 12:32:24   Another message
3             1          2        2012-07-04 14:00:00   Hello again

users_blocked

user_id    blocked_id
1          3

3 个答案:

答案 0 :(得分:0)

尝试:

select m.message_content,
       x.ft,
       x.other_id,
       x.most_recent
from (select if(from_id < to_id, concat(from_id,to_id), concat(to_id,from_id)) as ft,
             if(from_id = $my_id, to_id, from_id) as other_id,
             max(date_sent) as most_recent
      from users_messages um
      left join users_blocked ub1 
        on (um.from_id = ub1.blocked_id and ub1.user_id = $my_id)
      left join users_blocked ub2 
        on (um.to_id = ub2.blocked_id and ub2.user_id = $my_id)
      where ub1.blocked_id is null and ub2.blocked_id is null and
            (um.from_id = $my_id or um.to_id = $my_id)
      group by ft) x
join users_messages m
     on m.date_sent = x.most_recent and 
        m.from_id in ($my_id, x.other_id) and 
        m.to_id in ($my_id, x.other_id)
order by
    x.most_recent desc

SQLFiddle here

答案 1 :(得分:0)

这里我假设SimonKing想要来自users_messages表的消息内容,其中包括以下条件,

  1. 用户不应阻止任何一个方向,
  2. 用户之间传输的最新消息
  3. 这样,我修改了Mark Ba​​nnister查询如下,

    SELECT temp.* FROM  (
    SELECT um.*, concat(um.from_id,to_id) as direction FROM userMessages um
    LEFT JOIN userBlocked ub1 ON um.from_id = ub1.user_id AND um.to_id = ub1.blocked_id
    LEFT JOIN userBlocked ub2 ON um.to_id = ub2.user_id AND um.from_id = ub2.blocked_id 
    WHERE ub1.user_id is null AND ub1.blocked_id is null AND ub2.user_id is null AND ub2.blocked_id is null
    ORDER BY um.date_sent DESC
    ) temp
    GROUP BY direction
    

    SQL小提琴是http://sqlfiddle.com/#!2/bdc77/1/0

答案 2 :(得分:0)

据我所知,此请求的主要问题是结果只包含第一个日期,而不包含消息。要解决此问题,您可以执行此操作:

  1. 制作具有最新日期的准备数据集:

    选择to_id,from_id,max(date_sent)作为most_recent     来自users_messages m         在ub.user_id = $ my_id上左连接users_blocked ub             和(to_id,from_id)中的ub.blocked_id     哪里         (from_id = $ my_id或to_id = $ my_id)         和ub.blocked_id为空     通过...分组         to_id,from_id     订购         most_recent desc

  2. 我看到你通过两个字段to_id,from_id来搜索数据。这个子查询不是计算诸如此类事物的最佳位置:

    if(from_id < to_id, concat(from_id,to_id), concat(to_id,from_id)) as ft
    
    1. 然后只需从users_messages中选择其他所需数据,这些数据与我们的to_id,from_id和recent_date相匹配,来自准备好的表:

      中选择嗯。*
      (
      select to_id, from_id, max(date_sent) as most_recent
      from users_messages m
      left join users_blocked ub on ub.user_id = 1
      and ub.blocked_id in (to_id, from_id)
      where
      (from_id = 1 or to_id = 1)
      and ub.blocked_id is null
      group by
      to_id, from_id
      order by
      most_recent desc
      ) as prepared_messages
      left join users_messages um on um.from_id = prepared_messages.from_id
      and um.to_id = prepared_messages.to_id
      and um.date_sent = prepared_messages.most_recent