2 Stimmen

Ringkampf mit SQL

Ich habe das in einer MySQL-Datenbank:

Tabelle Nachricht
    sender_id int
    recipient_id int
    erstellt datetime
    [Titel, Text, etc... ausgelassen]

Ist es möglich, aus diesem, in einer einzigen Abfrage, eine Liste aller Benutzer zu erhalten, die mit einem bestimmten Benutzer mit der ID N kommuniziert haben (d.h. N erscheint entweder in sender_id oder recipient_id), geordnet nach erstellt, einschließlich des neuesten Werts von erstellt, ohne Duplikate (keine Sender/Empfänger-Paare N, M und M, N)?

Ich bin mir ziemlich sicher, dass die Antwort Nein lautet, aber ich habe Schwierigkeiten, mich zu überzeugen. Nachmittägliche Geistestrunkenheit.

Wenn Nein, welche effiziente Alternative würden Sie empfehlen?


EDIT: Oh Mann, Stack Overflow ist in diesen Tagen sehr lebhaft. 8 Antworten, bevor mir auffällt, dass ich vergessen habe anzugeben, dass ich den aktuellsten Wert von erstellt zusammen mit der anderen Benutzer-ID in jeder Zeile haben möchte.

4voto

Cruachan Punkte 15597

Versuchen Sie das

SELECT distinct recipient_id
FROM Message
WHERE sender_id = @id

UNION

SELECT distinct sender_id
FROM Message
WHERE recipient_id = @id

Die Union-Klausel entfernt Duplikate über die beiden Abfragen hinweg. Tatsächlich brauchen Sie die Distinct-Abfragen auch nicht, da die Union das auch für Sie erledigen wird (hat jemand eine Idee, ob es effizienter ist, distinct zu verwenden, um die Klauseln vorzufiltern oder einfach die Union alle Duplikate handhaben zu lassen?)

3voto

OMG Ponies Punkte 312816

Verwendung:

SELECT x.friend,
       MAX(x.created)
  FROM (SELECT t.recipient_id 'friend',
               t.created
          FROM NACHRICHT t
         WHERE t.sender_id = @id 
        UNION
        SELECT r.sender_id 'friend',
               r.created
          FROM NACHRICHT r
         WHERE r.recipient_id = @id) x
GROUP BY x.friend

1voto

Franz Punkte 11123

Nein, es ist ziemlich einfach zu machen.

SELECT DISTINCT IF(sender_id=4, recipient_id, sender_id) AS partner_id
FROM message
WHERE sender_id=4 OR recipient_id=4

1voto

Hier ist meiner :)

select id, max(created) as lastMessage
(
    select sender_id as id, created
    from Message
    union
    select recipient_id as id, created
    from Message
) as MergedMessage
where id = ?id
group by id
order by max(created) desc

Das ist es :

  • ohne Duplikate
  • sortiert nach created absteigend

0voto

René Nyffenegger Punkte 37584

Natürlich hast du offensichtlich Schwierigkeiten, dich selbst zu überzeugen, sonst hättest du nicht gefragt. Und ich bin mir ziemlich sicher, dass die Antwort Ja lautet. Dennoch ist es etwas schwierig, die richtige Lösung zu finden, ohne einige Besonderheiten über die zugrunde liegenden Daten zu kennen.

Es geht wahrscheinlich in die Richtung von

select 
  sender_id,
  recipient_id
from
  message
where
 (sender_id    = n or 
  recipient_id = n   )
order by
  created desc

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X