2013-07-04 92 views
0

我真的很感謝任何幫助,試圖簡化MySQL查詢。查詢的目的是從消息表(users_messages)中檢索具有以下列的消息:message_id,from_id,to_id,message_content,date_sent。試圖簡化MySQL查詢

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 
+1

請提供您的表結構(一個或多個)。另外 - 它返回'message_content',但它不是正確的值?或者它沒有返回任何東西? – ethrbunny

+3

這並不算太壞。地獄,你可以閱讀而不用滾動,這永遠是一種獎勵! –

+0

不可怕,但我可能只是得到一個被阻止的用戶數組,並做一個不爲from_id – timpone

回答

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

+0

謝謝馬克。我試過這個,並且在'where clause'中收到一個錯誤「Unknown column'm.from_id'」。我在子查詢中將「users_messages」更改爲「users_messages m」,現在返回0結果。 –

+0

@SimonKing:我做了一些改動 - 現在就試試。 –

+0

現貨。絕對完美。非常感謝 –

0

這裏我假定SimonKing想,從users_messages表,其包括以下條件的消息內容,

  1. 用戶不應阻止任一方向,
  2. 用戶之間傳送的最新的郵件

這樣,我修改了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

+0

這依賴於MySQL中觀察到但未記錄的行爲,這在未來的版本中可能不起作用;它已經從MariaDB(MySQL的開源分支)中刪除。 –

+0

@Mark Ba​​nnister,給我一些網址,以獲取有關此 –

+0

的進一步信息在這裏:https://kb.askmonty.org/en/group-by-trick-has-been-optimized-away/ –

0

按照我的理解,這個請求的主要問題是,結果只包含第一日期,而不是消息。爲了解決這個問題,你可以這樣做:

  1. 化妝準備的數據集,這將有最新的日期:

    選擇to_id,from_id,MAX(DATE_SENT)作爲most_recent 從users_messages中號 左連接users_blocked UB在ub.user_id = $ my_id 和ub。blocked_id在(to_id,from_id) 其中 (from_id = $添加my_id或to_id = $添加my_id) 和ub.blocked_id爲空 組由 to_id,通過 most_recent降序from_id 順序

我看到你用兩個collumns 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