Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL-Gruppe, indem sie sich wie Facebook-Messaging verhält (mssql sp)

Die Antwort ähnelt Ihrer frühere Frage . Allerdings muss nun berücksichtigt werden, dass der @user könnte jeder Benutzer in der Nachricht sein.

In diesem Fall row_number() ist nicht direkt hilfreich.

Hier sind die Unterschiede. Es gibt jetzt eine Unterabfrage, um die beiden Benutzer in eine "kanonische" Reihenfolge zu bringen. Alle Nachrichten zwischen ihnen haben also denselben User1 und User2 (basierend auf alphabetischer Reihenfolge).

Die partition by -Klausel verwendet diese Spalten, sodass alle Nachrichten in seqnum enthalten sind Berechnung. Die Users table ruft jetzt direkt Informationen über den aktuellen Benutzer ab.

select FromUser, ToUser, Message, [Date], UserId, UserFullName, UserName, UserPhoto
from (SELECT CM.FromUser, CM.ToUser, CM.Message, CM.[Date], U.UserId,
             U.UserFullName, U.UserName, U.UserPhoto,
             row_number() over (partition by CM.User1, CM.User2
                                order by CM.[Date] desc) as seqnum
      FROM (select CM.*,
                   (case when FromUser < ToUser then FromUser else ToUser end) as User1,
                   (case when FromUser < ToUser then ToUser else FromUser end) as User2
            from ConversationMessages CM
           ) CM CROSS JOIN
           (select *
            from Users U
            where @user = u.UserName
           ) U
      WHERE @user in (CM.ToUser, CM.FromUser)
     ) s
WHERE seqnum = 1
ORDER BY s.[Date] DESC ;

BEARBEITEN:

Das Obige gibt die Benutzerinformationen für @user zurück . Für den anderen Teilnehmer:

select FromUser, ToUser, Message, [Date], UserId, UserFullName, UserName, UserPhoto
from (SELECT CM.FromUser, CM.ToUser, CM.Message, CM.[Date], U.UserId,
             U.UserFullName, U.UserName, U.UserPhoto,
             row_number() over (partition by CM.User1, CM.User2
                                order by CM.[Date] desc) as seqnum
      FROM (select CM.*,
                   (case when FromUser < ToUser then FromUser else ToUser end) as User1,
                   (case when FromUser < ToUser then ToUser else FromUser end) as User2
            from ConversationMessages CM
           ) CM JOIN
           Users U
           on U.UserName <> @user and
              U.UserName in (CM.FromUser, CM.ToUser)
      WHERE @user in (CM.ToUser, CM.FromUser)
     ) s
WHERE seqnum = 1
ORDER BY s.[Date] DESC ;