2017-01-10 4 views
0

Ich habe zwei Tabellen:verschachtelte Abfragen, Unterabfrage SQL

select * from friends; 
user_id | friend_id |   created_at   
---------+-----------+---------------------------- 
user | user2  | 2017-01-09 21:29:56.31972 
user | user3  | 2017-01-09 21:29:58.567925 
user | user4  | 2017-01-09 21:30:01.200806 
user2 | user  | 2017-01-09 21:30:49.498912 
user3 | user  | 2017-01-09 21:30:53.549042 
user4 | user  | 2017-01-09 21:30:56.519135 
id | user_id | user_from | message 
----+---------+-----------+--------- 
    1 | user | user2  | hey 
    2 | user | user3  | de 
    3 | user | user4  | bal 
    4 | user | user3  | ok 
    5 | user | user3  | nice 
    6 | user | user4  | cana 
    7 | user | user2  | doc 

Diese SQL-Anweisung erfolgreich ruft die letzte Nachricht an einen Benutzer. Beispielsweise. Die letzte Meldung von user3 an Benutzer gesendet

select id, user_from, message 
from messages 
WHERE user_id = 'user' 
AND user_from = 'user3' 
ORDER BY id DESC 
limit 1; 
id | user_from | message 
----+---------+--------- 
    5 | user3 | nice 

Ich brauche eine Sammlung von Nachrichten abzurufen. Jede Nachricht stellt die letzte Nachricht von einem Freund zu einem Benutzer gesendet

Was ich brauche, ist eine Abfrage zu kombinieren, so dass ich so etwas wie dieses

erhalten
id | user_from | message 
----+-----------+--------- 
    7 | user2  | doc 
    5 | user3  | nice 
    6 | user4  | cana 

Antwort

0

distinct on ist die einfachste Lösung hier.

Dieser verwendet eine PostreSQL Erweiterung des SQL-Standard gibt es auch eine standardisierte Möglichkeit dies mit Fensterfunktionen zu tun, aber es ist komplizierter, und ein möglicherweise ineffizienter Weg einer Selbstverknüpfung verwenden.

+0

Das hat nicht funktioniert: ERROR: SELECT DISTINCT ON Ausdrücke Anfangs ORDER BY-Ausdrücke müssen übereinstimmen LINE 1: Wählen Sie DISTINCT ON (user_from) id, user_from, Nachricht – user1000622

+0

ich die Abfrage mit der folgenden modifizierten ... wählen DISTINCT ON (user_from) ID, user_from, Nachricht von Nachrichten WHERE user_id = 'user' UND user_from = 'user3' ORDER BY user_from, ID DESC; ID | user_from | Meldung ---- + ----------- + --------- 5 | Benutzer3 | schön – user1000622

+0

Aber immer noch nicht das, was ich will. Ruft nur eine Zeile ab – user1000622

-1

Beginnen Sie mit Ihrer Datenbank zu normalisieren, relationalen Datenbanken brauche das.

Ich bin nicht sicher, wie vertraut Sie mit db Design und SQL sind. Aber schauen Sie in Joins verwenden, die mit einer normalisierten db besser funktionieren;)

Informieren Sie sich über die Normalisierung hier http://www.studytonight.com/dbms/database-normalization.php

Auch nachschlagen schließt sich auf w3schools oder tutorialspoint, werden Sie bekommen, was Sie brauchen

0

Sie können Join und Fensterfunktion verwenden (für Ihren Fall ist row_number). Wenn die erste Tabelle friends ist und die zweite messages ist, könnte diese Lösung funktionieren (noch nicht getestet).

select id, user_from, message 
from (
    select m.* 
    , row_number() over(partition by m.user_from order by f.created_at desc) as N 
    from friends f, messages m 
    where f.user_id = m.user_id and f.friend_id = m.user_from) x 
where N = 1;