2015-12-17 20 views
9

我知道以前也有类似的问题,但没有一个具有相同的条件,他们的答案对这种情况不起作用。从每次对话中获取最后一条消息

包含的消息的表看起来像这样:

id | owner_id | recipient_id | content  | created 
1 |  1 |   2 | Hello  | 2015-12-08 20:00 
2 |  2 |   1 | Hey   | 2015-12-08 20:10 
3 |  3 |   1 | You there? | 2015-12-08 21:00 
4 |  1 |   3 | Yes   | 2015-12-08 21:15 
5 |  4 |   1 | Hey buddy | 2015-12-08 22:00 

而且我们说,我查询用户ID 1的谈话,预期的结果是:

id | owner_id | recipient_id | content  | created 
5 |  4 |   1 | Hey buddy | 2015-12-08 22:00 
4 |  1 |   3 | Yes   | 2015-12-08 21:15 
2 |  2 |   1 | Hey   | 2015-12-08 20:10 

我试过很多的组合使用,联合和子查询,但没有一个给出了预期的结果。

我正在寻找MySQL中的答案,但是这将用于CakePHP 2开发的项目中,所以如果有一个Cake特定的方法来做到这一点,那就太棒了。

这是我尝试过的一个查询,但它不工作。我相信甚至没有接近我所需要的。

SELECT 
    IF (owner_id = 1, recipient_id, owner_id) AS Recipient, 

    (
     SELECT 
      content 
     FROM 
      messages 

     WHERE 
      (owner_id = 1 AND recipient_id = Recipient ) 
     OR 
      (owner_id = Recipient AND recipient_id = 1) 

     ORDER BY 
      created DESC 

     LIMIT 1 
    ) 
FROM 
    messages 

WHERE 
    owner_id = 1 
OR 
    recipient_id = 1 

GROUP BY 
    Recipient; 
+2

表中是否有唯一键? – Timekiller

+0

是的,我更新了这个问题(拼错了几个ID)。 – Camilo

+0

您是否可以包含您在问题中尝试过的SQL查询? – summea

回答

5
select t.* 
    from 
     t 
     join 
     (select user, max(created) m 
      from 
       (
       (select id, recipient_id user, created 
        from t 
        where owner_id=1) 
       union 
       (select id, owner_id user, created 
        from t 
        where recipient_id=1) 
       ) t1 
      group by user) t2 
    on ((owner_id=1 and recipient_id=user) or 
     (owner_id=user and recipient_id=1)) and 
     (created = m) 
    order by created desc 

example on sqlfiddle

+0

这个查询返回预期的结果,非常感谢你!尽管我仍在试图弄清楚它是如何工作的。 – Camilo

+1

不客气!我可以写一些爆炸,如果你想 – splash58

+0

这将是伟大的@ splash58 – Camilo

0

这应该做的伎俩:

$joins = array(
    array('table' => 'conversations', 
     'alias' => 'Conversation2', 
     'type' => 'LEFT', 
     'conditions' => array(
      'Conversation.id < Conversation2.id', 
      'Conversation.owner_id = Conversation2.owner_id', 
     ) 
    ), 
    array('table' => 'conversations', 
     'alias' => 'Conversation3', 
     'type' => 'LEFT', 
     'conditions' => array(
      'Conversation.id < Conversation3.id', 
      'Conversation.recepient_id = Conversation3.recepient_id', 
     ) 
    ) 

); 

$conditions = array(
    'OR' => array(
     array(
      'Conversation2.id'=>null, 
      'Conversation.owner_id' => $ownerId 
     ), 
     array(
      'Conversation3.id'=>null, 
      'Conversation.recipient_id' => $ownerId 
     ), 
    ) 
); 

$order = array('Conversation.created'=>'DESC'); 

$lastConversations=$this->Conversation->find('all',compact('conditions','joins','order')); 

提供该表的名称是conversations和模型的名称是Conversation。它基于Retrieving the last record in each group接受的答案中描述的技术。

+0

这一个似乎是接近。目前唯一的问题是结果不是最近订购的。试图添加“订单”参数,但它没有解决问题。 – Camilo

+0

@Camilo我已经添加了ORDER BY子句。 –

+0

谢谢。我试过了,问题仍然存在。还注意到分组不能按预期工作。我会坚持SQL答案,谢谢! – Camilo

相关问题