2015-12-17 3 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 

Я пробовал много комбинаций, используя JOINs и подзапросы, но ни один из них не дал ожидаемых результатов.

Я ищу ответ в MySQL, но это будет использоваться в проекте, разработанном под CakePHP 2, поэтому, если есть конкретный способ сделать торт, это будет здорово.

Вот один из вопросов, которые я пробовал, но он не работает. Я считаю, что даже близко не к тому, что мне нужно.

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

Да, я обновил вопрос (неправильно использовал несколько идентификаторов). – 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

Смежные вопросы