Защо не работи с 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 клауза поддържа набора от резултати в приличен размер.