Mysql
 sql >> база данни >  >> RDS >> Mysql

показване на последния коментар, който има само 1 коментар на потребител

Защо не работи с GROUP BY

SELECT * не може да се използва с GROUP BY; това е невалиден SQL. GROUP BY не избира редове от таблицата. Създава групи от редове, като използва предоставените изрази, след което от всяка група генерира нов запис и изчислява всяка колона от този нов запис, използвайки стойностите, включени в израза.

Колоните, които се показват в SELECT клаузата трябва да отговаря на едно от следните правила:

  • се появяват и в GROUP BY клауза;
  • се използват с GROUP BY агрегатни функции ;
  • са функционално зависими от колоните, които се показват в GROUP BY клауза.

Докато * е пряк път за всички имена на колони на таблицата(ите), използвани от заявката, за вашата заявка само user колона отговарят на едно от изискванията по-горе.

Преди версия 5.7.5 MySQL не е приложил третото правило по-горе. Използва се за приемане на заявки, които съдържат SELECT колони на клаузи, които не следват нито една от GROUP BY изисквания. Стойността, върната от заявката за такива колони, беше неопределена .

От версия 5.7.5 MySQL отхвърля GROUP BY заявки, които отговарят на изискванията.

Решението

Така или иначе, решението на вашия проблем не включва GROUP BY . Може лесно да се постигне с помощта на LEFT JOIN с правилните условия:

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

Как работи

Той се присъединява към таблицата comments , с псевдоним lc ("lc" от "последния коментар" на потребител) срещу себе си, псевдоним като nc ("nc" от "по-нов коментар"). Клаузата за присъединяване съответства на всеки запис на lc с всички записи на nc които принадлежат на един и същ потребител (lc.user = nc.user ) и са по-нови (lc.id < nc.id; Предположих, че идентификаторите се присвояват последователно и по-новите коментари имат по-големи стойности за id ).

Използването на LEFT JOIN гарантира, че всеки ред от lc се появява в резултата от съединяването, дори когато не е намерен съответстващ ред в nc (защото няма по-нов коментар от същия потребител). В този случай NULL се използва вместо полетата на nc . WHERE клаузата запазва в крайния набор от резултати само редовете, които имат NULL в nc.id; това означава в lc част съдържат най-скорошния коментар на всеки потребител.

SELECT клаузата съдържа всички полета на lc (тези от nc всички са NULL , така или иначе). ORDER BY клаузата може да се използва за сортиране на резултатния набор. ORDER BY lc.id DESC поставя най-новите коментари на първо място и LIMIT клауза поддържа набора от резултати в приличен размер.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Данните за предупреждение за дата на Mysql са съкратени

  2. Visual Studio - Неуспешно свързване на таблицата на базата данни MySql с DataSet

  3. MySQL :сума от всеки ден

  4. Как да създам обратна подредена променлива в моя sql

  5. защо съхранената процедура, извикана от sqlalchemy, не работи, но извикването от workbench работи?