2017-01-15 2 views
0

Ich habe eine Tabelle message, die 4 Hauptsäulen:Subquery mit mehreren Spalten in where-Klausel

  • id: Nachricht von id.
  • interlocutor_id: Die ID des Gesprächspartners.
  • timestamp: Der Zeitstempel, zu dem die Nachricht gesendet wurde.
  • expiration: Der Zeitstempel, wann die Nachricht abläuft. Wenn der Wert unter dem aktuellen Zeitstempel liegt, ist er abgelaufen.

Ich wünsche alle letzten Nachrichten von jedem Gesprächspartner zu bekommen (auch wenn sie abgelaufen ist), und ich möchte auch alle nicht abgelaufene Nachrichten (auch wenn sie nicht die letzten sind).

Ich versuchte diese Abfrage aber dann verstand ich, dass ich nicht eine Unterabfrage mit mehreren Spalten machen kann:

SELECT * FROM message 
WHERE (expiration > 'CURRENT_TIMESTAMP') 
OR (id IN (SELECT id, MAX(timestamp) FROM message GROUP BY interlocutor_id)) 

Wie soll ich tun?

Antwort

1

Ich denke, das ist das, was Sie beabsichtigen:

SELECT m.* 
FROM message m 
WHERE (m.expiration > 'CURRENT_TIMESTAMP') OR 
     m.timestamp = (SELECT MAX(timestamp) 
        FROM message m2 
        WHERE m2.interlocutor_id = m.interlocutor_id 
        ); 

Auch wenn Sie 'CURRENT_TIMESTAMP' sagen, tun Sie so etwas wie datetime('now', 'localtime') bedeuten.

+0

Vielen Dank! Ihre Anfrage funktioniert gut, aber ich weiß nicht warum. Es sollte in der Lage sein, unerwünschte Nachrichten einzuschließen, wenn die Nachricht nicht die letzte ist und abgelaufen ist (also eine unerwünschte Nachricht), aber es gibt eine andere Nachricht von einem anderen Gesprächspartner, der sein letzter ist und genau denselben Zeitstempel hat , sollte es nicht? Ich weiß nicht, warum es keine solche Nachricht enthält (ich habe es getestet). – Yairopro

+0

Ich wusste nicht, dass es eine SQL-Methode gab, um den aktuellen Zeitstempel zu erhalten. Aber ja, ich meinte es. Vielen Dank – Yairopro

1

Eine Möglichkeit, dies zu tun, wäre die Teilnahme an einer Unterabfrage. Erstellen Sie eine Unterabfrage, die für jede interlocutor_id das maximale Datum zurückgibt, und verlassen Sie sie.

SELECT M.* 
FROM message M 
LEFT JOIN 
    (SELECT interlocutor_id, MAX(timestamp) ts FROM message GROUP BY interlocutor_id) LastTime 
    on LastTime.interlocutor_id = M.interlocutor_id AND m.timestamp = Lasttime.ts 
WHERE (expiration > 'CURRENT_TIMESTAMP') 
OR LastTime.id is not null 

Alternativ könnten Sie aussehen wie bei VORHANDEN eher als ein in einer Unterabfrage suchen Mitglied werden, abhängig von Ihren Daten dies besser ausführen kann.