2016-04-18 9 views
0

passend Ich habe eine Tabelle private_messages mit der folgenden Struktur genannt:mehr Zeilen in der Tabelle überprüft und sie als 1 gezählt, wenn Reihen

id  message_from  message_to 

Ich versuche, die Anzahl der aktiven Chat-Räume, um zu bestimmen, aber die Tabelle speichert alle gesendeten und empfangenen Nachrichten, daher kann es viele Zeilen geben, in denen Alice in message_from und in message_to ist.

Angenommen meine private_messages Tabelle 4 Reihen hat:

id message_from message_to 
1 Alice   conor 
2 Alice   conor 
3 connor   Alice 
4 Anderson  conor 

Das Gespräch zwischen Alice und Conor sollte als 1 in Betracht gezogen werden. Deshalb, wenn ich echo, sagen wir $active_conversations, sollte die Nummer 2 gedruckt werden.

Ich gehe davon aus, dass ein Array beteiligt? d.h. $conversations = [];. Aber ich weiß oder verstehe nicht, was ich darüber hinaus tun soll.

+0

Eigentlich sollte Ihre Tabelle eine weitere Spalte mit dem Namen 'conversation_id' haben, oder im schlimmsten Fall brauchen Sie individuelle Tabellen für jede Konversation. – Manikiran

+0

Was ist Ihre gewünschte Ausgabe? –

Antwort

0
select count(id) from private_messages group by message_from,message_to 

dann erhalten Sie entsprechende Ergebnis

+0

Die Abfrage in dieser Frage gibt die Anzahl der Zeilen in private_messages zurück, die von einer Seite einer Konversation/eines Raums stammen. Für die in der Frage angegebenen Beispieldaten würde dies drei Zeilen ergeben, die nicht in einer bestimmten Reihenfolge garantiert sind, mit Werten von 2,1 und 1. Dies kann ein "passendes Ergebnis" sein. Aber ich würde dieses Ergebnis nicht als "die Anzahl der aktiven Chatrooms" bezeichnen. – spencer7593

0

Wenn Sie nur eine Anzahl von Gesprächen erhalten möchten, können Sie so etwas wie dieses

SELECT COUNT(DISTINCT 
      CONCAT(
        LEAST(message_from,message_to), 
        '->', 
        GREATEST(message_from,message_to) 
        ) 
      ) AS active_conversations 
FROM private_messages; 

sqlfiddle

Ausgang verwenden:

active_conversations 
2 

Wenn Sie Details der Gespräche erhalten können Sie diese

SELECT DISTINCT 
     LEAST(message_from,message_to) as FirstPerson, 
     GREATEST(message_from,message_to) as SecondPerson 
FROM private_messages; 

sqlfiddle

Ausgang verwenden:

FirstPerson  SecondPerson 
Alice   conor 
Anderson  conor 
0

Eines der Probleme ist, dass die Tupel ('connor',‘ Alice ') und (' Alice ',' connor ') in `private_messages` repräsentieren die gleiche Konversation/Raum, egal was du zählst.

Ein Ansatz wäre eine Gesamtzahl der verschiedenen Werte zu erhalten und durch zwei zu teilen, aber das scheint nicht wirklich der richtige Weg zu sein. (Wir können einige Grenzfälle Setup, wo das Ergebnis wir zurück sind keine ganze Zahl ist, oder kleiner ist als die tatsächliche Anzahl der aktiven Räume .... zB

id message_from message_to 
-- ------------ ---------- 
1 Alice   conor 
2 Alice   conor 
3 conor   Alice 
4 Anderson  conor 
5 Cooper   Alice 
6 Dalton   Allman 

Ein anderer Ansatz wäre es, die Werte neu zu ordnen in die Tupel (swapping message_from und message_to) in einigen Zeilen, die mit message_from und message_two auf der anderen Seite der Konversation übereinstimmen. Zum Beispiel könnten wir message_from und message_to vergleichen und sie austauschen, wenn message_to niedriger ist als message_from.

Zur Veranschaulichung verwenden Sie einen Ausdruck, um Werte zurückzugeben, die in den Spalten m_one und m_two angezeigt werden:

id message_from message_to  m_one  t_two 
-- ------------ ----------  -----  ----- 
1 Alice   conor   Alice  conor 
2 Alice   conor   Alice  conor 
3 conor   Alice   Alice  conor 
4 Anderson  conor   Anderson conor 
5 Cooper   Alice   Alice  Cooper 
6 Allman   Dalton   Allman  Dalton 

Und dann konnten wir die unterschiedlichen Werte der (m_one, m_zwei) Tupel zählen.

Ein dritter Ansatz wäre, alle Tupel zu verwerfen, bei denen der Wert message_from höher ist als message_to, um eine Seite der Konversation/des Raumes loszuwerden. Und dann eine Zählung der verschiedenen Tupel, die übrig bleiben. Dies würde jedoch einige Gespräche/Räume, die Nachrichten in nur einer Richtung hatten, möglicherweise ausschließen.

id message_from message_to  m_one  t_two 
-- ------------ ----------  -----  ----- 
1 Alice   conor   Alice  conor 
2 Alice   conor   Alice  conor 
3 conor   Alice   Alice  conor 
4 Anderson  conor   Anderson conor 
5 Cooper   Alice   (NULL)  (NULL) 
6 Allman   Dalton   Allman  Dalton 

(Wir werden beiseite eine Diskussion über die Ecke bei einem Gespräch/Raum gesetzt, wo message_from zu message_to gleich ist.)


Die SQL wir wirklich auf das, was Algorithmus schreiben, hängt wir möchte implementieren.

Wir könnten eine GROUP BY verwenden, um "übereinstimmende" Zeilen zu reduzieren und eine Zählung zu erhalten. Oder wir könnten eine COUNT(DISTINCT foo) verwenden, um eine Anzahl unterschiedlicher Werte zu erhalten. Wenn wir einen Algorithmus auswählen, der Werte "vertauschen" muss, können wir Ausdrücke verwenden, die die Funktionen LEAST und GREATEST verwenden. Oder MySQL IF() - Funktion oder CASE-Ausdrücke.

Wenn wir Zeilen von der Zählung ausschließen möchten, können wir ein Prädikat in die WHERE-Klausel aufnehmen.

Alle diese sind möglich, und es gibt mehrere Möglichkeiten, das angegebene Ergebnis zu erzielen.

Verwandte Themen