2015-12-17 9 views
9

So che domande simili erano già state fatte prima, ma nessuna di queste aveva le stesse condizioni e le loro risposte non funzionavano per questo caso.Ricevi l'ultimo messaggio da ogni conversazione

La tabella contenente i messaggi si presenta così:

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 

E diciamo interrogo le conversazioni per User ID 1, il risultato atteso è:

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 

ho provato molte combinazioni, utilizzando JOINs e sottoquery ma nessuno di questi ha dato i risultati attesi.

Sto cercando una risposta in MySQL ma verrà utilizzata in un progetto sviluppato con CakePHP 2, quindi se c'è un modo specifico per Cake in questo modo sarebbe fantastico.

Questa è una delle query che ho provato ma non funziona. Credo che non sia nemmeno vicino a quello di cui ho bisogno.

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

C'è una chiave univoca nel tuo tavolo? – Timekiller

+0

Sì, ho aggiornato la domanda (erano stati visualizzati alcuni ID). – Camilo

+0

Puoi gentilmente includere le query SQL che hai provato nella tua domanda? – summea

risposta

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

Questa query restituisce i risultati previsti, grazie mille! Anche se sto ancora cercando di capire come funziona. – Camilo

+1

Siete i benvenuti! posso scrivere alcune esplosioni se vuoi – splash58

+0

Sarebbe bello @ splash58 – Camilo

0

Questo dovrebbe fare il trucco:

$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')); 

A condizione che il nome della tabella è conversations e il nome del modello è Conversation. Si basa sulla tecnica descritta nella risposta accettata di Retrieving the last record in each group.

+0

Questo sembra essere vicino. L'unico problema finora è che i risultati non vengono ordinati dal più recente. Ho provato ad aggiungere il parametro "ordine" ma non ha risolto il problema. – Camilo

+0

@Camilo Ho aggiunto la clausola ORDER BY. –

+0

Grazie. Ho provato e il problema persiste ancora. Inoltre notato che il raggruppamento non funziona come previsto. Attaccherò alla risposta SQL, grazie comunque! – Camilo

Problemi correlati