sql >> Databasteknik >  >> RDS >> Mysql

visa sista kommentaren som bara 1 kommentar per användare

Varför det inte fungerar med GROUP BY

SELECT * kan inte användas med GROUP BY; det är ogiltig SQL. GROUP BY väljer inte tabellrader. Den skapar grupper av rader med hjälp av de angivna uttrycken och sedan, från varje grupp, genererar den en ny post och beräknar varje kolumn i denna nya post med hjälp av värdena som är involverade i uttrycket.

Kolumnerna som visas i SELECT klausul måste uppfylla en av följande regler:

  • visas även i GROUP BY klausul;
  • används med GROUP BY samla funktioner ;
  • är funktionellt beroende av kolumnerna som visas i GROUP BY klausul.

Medan * är en genväg för alla kolumnnamn för tabellen/tabellerna som används av frågan, för din fråga är endast user kolumnen uppfyller ett av kraven ovan.

Före version 5.7.5 MySQL implementerade inte den tredje regeln ovan. Det brukade acceptera frågor som innehåller SELECT satskolumner som inte följer någon av GROUP BY krav. Värdet som returnerades av frågan för sådana kolumner var obestämt .

Sedan version 5.7.5 avvisar MySQL GROUP BY frågor som uppfyller kraven.

Lösningen

Hur som helst, lösningen på ditt problem involverar inte GROUP BY . Det kan enkelt göras med en LEFT JOIN med rätt villkor:

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å fungerar det

Den förenar tabellen comments , alias som lc ("lc" från den "sista kommentaren" av en användare) mot sig själv, alias som nc ("nc" från "nyare kommentar"). Join-satsen matchar varje post i lc med alla inmatningar av nc som tillhör samma användare (lc.user = nc.user ) och är nyare (lc.id < nc.id; Jag antog att ID:n tilldelas sekventiellt och nyare kommentarer har större värden för id ).

Användningen av LEFT JOIN säkerställer att varje rad av lc visas i resultatet av sammanfogningen, även när ingen matchande rad hittas i nc (eftersom det inte finns någon nyare kommentar från samma användare). I det här fallet NULL används istället för fälten för nc . WHERE satsen behåller i den slutliga resultatuppsättningen endast de rader som har NULL i nc.id; detta betyder i lc del innehåller de den senaste kommentaren från varje användare.

SELECT klausulen innehåller alla fält i lc (de av nc är alla NULL , i alla fall). ORDER BY klausul kan användas för att sortera resultatuppsättningen. ORDER BY lc.id DESC sätter de senaste kommentarerna först och LIMIT klausul håller resultatet inställt på en anständig storlek.



  1. Kan inte komma åt fältet genom viloläge på Oracle-databas på olika användarutrymmen med endast utvalda privilegier

  2. Cakephp:medan du infogar ett litet fält. Får bara 0 eller 1

  3. Hur man anropar exempel helloword func med hjälp av en java-kod

  4. Hur kan jag starta och kontrollera min MySQL-logg?