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

vis sidste kommentar som kun 1 kommentar pr. bruger

Hvorfor virker det ikke med GROUP BY

SELECT * kan ikke bruges med GROUP BY; det er ugyldig SQL. GROUP BY vælger ikke tabelrækker. Den opretter grupper af rækker ved hjælp af de angivne udtryk, og fra hver gruppe genererer den en ny post og beregner hver kolonne i denne nye post ved hjælp af de værdier, der er involveret i udtrykket.

De kolonner, der vises i SELECT klausul skal opfylde en af ​​følgende regler:

Mens * er en genvej til alle kolonnenavnene på tabellen(erne), der bruges af forespørgslen, for din forespørgsel kun user kolonnen opfylder et af kravene ovenfor.

Før version 5.7.5 MySQL implementerede ikke den tredje regel ovenfor. Det plejede at acceptere forespørgsler, der indeholdt i SELECT klausulkolonner, der ikke følger nogen af ​​GROUP BY krav. Den værdi, der blev returneret af forespørgslen for sådanne kolonner, var ubestemt .

Siden version 5.7.5 afviser MySQL GROUP BY forespørgsler, der opfylder kravene.

Løsningen

Uanset hvad, så involverer løsningen af ​​dit problem ikke GROUP BY . Det kan nemt opnås ved at bruge en LEFT JOIN med de korrekte betingelser:

SELECT lc.*
FROM comments lc               # 'lc' from 'last comment'
    LEFT JOIN comments nc      # 'nc' from 'newer comment'
        ON lc.user = nc.user   # both comments belong to the same user
        AND lc.id < nc.id      # 'nc' is newer than 'lc'
WHERE nc.id IS NULL            # there is no 'newer comment'
ORDER BY lc.id DESC
LIMIT 10

Sådan virker det

Det forbinder tabellen comments , kaldet lc ("lc" fra den "sidste kommentar" fra en bruger) mod sig selv, kaldet nc ("nc" fra "nyere kommentar"). Join-klausulen matcher hver indgang i lc med alle indtastninger af nc der tilhører den samme bruger (lc.user = nc.user ) og er nyere (lc.id < nc.id; Jeg antog, at id'erne er tildelt sekventielt, og nyere kommentarer har større værdier for id ).

Brugen af ​​LEFT JOIN sikrer, at hver række af lc vises i resultatet af joinforbindelsen, selv når der ikke findes nogen matchende række i nc (fordi der ikke er nogen nyere kommentar fra den samme bruger). I dette tilfælde NULL bruges i stedet for felterne i nc . WHERE klausul beholder i det endelige resultatsæt kun de rækker, der har NULL i nc.id; dette betyder i lc del, de indeholder den seneste kommentar fra hver bruger.

SELECT klausulen indeholder alle felterne i lc (dem af nc er alle NULL , alligevel). ORDER BY klausul kan bruges til at sortere resultatsættet. ORDER BY lc.id DESC sætter de seneste kommentarer først og LIMIT klausul holder resultatet sat til en anstændig størrelse.



  1. 3 metoder til at forbinde MDF-fil til SQL Server

  2. returnerer nuller for datoer, der ikke eksisterer MYSQL GROUP BY

  3. Hvordan kan jeg få cx-oracle til at binde resultaterne af en forespørgsel til en ordbog i stedet for en tuple?

  4. Hvordan udtrækker man medianværdi?