sql >> Database teknologi >  >> RDS >> Mysql

Bestil valg baseret på deltagelsesresultater (Sortér samtaler på sidst sendt besked)

Problemet skyldes en MySQL-specifik udvidelse til adfærden for GROUP BY klausul. Andre databaser ville give en fejl... noget, der ligner on-aggregation i SELECT-listen". (Vi kan få MySQL til at kaste en lignende fejl, hvis vi inkluderer ONLY_FULL_GROUP_BY i sql_mode.)

Problemet med udtrykket messages.created er, der refererer til en værdi fra en ubestemt række i GROUP BY. ORDER BY operationen sker meget senere i behandlingen, efter GROUP BY operationen.

For at få det "seneste" oprettet for hver gruppe, skal du bruge et aggregat udtryk MAX(messages.created) .

At få de andre værdier fra den samme række er lidt mere kompliceret.

Forudsat at created er unik inden for en given conversation_id gruppe (eller, hvis der ikke er garanti for, at den ikke er unik, og du er okay med at returnere flere rækker med samme værdi for created ...

For at få den seneste created for hver conversation_id

SELECT lm.conversation_id
     , MAX(lm.created) AS created
  FROM conversation lc
  JOIN message lm
    ON lm.conversation_id = lc.id
 WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
 GROUP BY lm.conversation_id

Du kan bruge det som en indlejret visning for at få hele rækken med den seneste created

SELECT c.*
     , m.*
  FROM ( SELECT lm.conversation_id
              , MAX(lm.created) AS created
           FROM conversation lc
           JOIN message lm
             ON lm.conversation_id = lc.id
          WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
          GROUP BY lm.conversation_id
       ) l
  JOIN conversation c
    ON c.id = l.conversation_id
  JOIN messages m
    ON m.conversation_id = l.conversation_id
   AND m.created         = l.created
 WHERE (c.creator_id = :userId OR c.to_id = :userId)

BEMÆRKNINGER:

Du kan tilføje en ORDER BY klausul for at bestille rækkerne returneret, som du har brug for.

WHERE klausul på den ydre forespørgsel er sandsynligvis overflødig og unødvendig.

Vi foretrækker at undgå at bruge SELECT * , og foretrækker eksplicit at angive de udtryk, der skal returneres.




  1. Multi-Cloud-implementering til MySQL-replikering

  2. MySQL InnoDB-tabeller er korrupte - hvordan rettes det?

  3. Hvordan jeg gemmer og henter et billede på min server i en java webapp

  4. ListView Control Tutorial-02