Не сте разбрали как GROUP BY работи в SQL, поради функция на MySQL. В стандартния SQL всяка неагрегирана колона в оператора SELECT ТРЯБВА да бъде в клаузата GROUP BY (има изключение за колони, чиито стойности са 100% зависими от колона, която вече е в клаузата GROUP BY, въпреки че няколко варианта на SQL поддържат това изключение) .
MySQL не налага това по подразбиране, но стойностите на кои редове се използват за тези колони не е дефинирано. Въпреки че може да получите това, което искате, може и да не го направите. И дори да го направите, има шанс това да се промени в бъдеще.
Подреждането обикновено е независимо от GROUP BY, въпреки че ако не посочите клауза ORDER, тогава резултатите ще бъдат подредени въз основа на това, което е било необходимо за извършване на ГРУПИРАНЕТО (т.е. ако това помага да се подредят редовете в един ред, за да се направи GROUP BY тогава MySQL няма да си направи труда да пренареди записите след това, освен ако изрично не му кажете да го направи с клауза ORDER BY).
Така че с текущите ви данни, групирането по ads_post_id стойността на id, която се връща, може да бъде 22, 23, 24, 104, 250, 253 или 767. Кое MySQL ще избере да използва не е дефинирано.
С текущата ви корекция на данните това е тривиално, тъй като можете просто да получите MAX id:-
SELECT ads_post_id, MAX(id)
FROM fb_ads
GROUP BY ads_post_id
LIMIT 6
MAX ще върне 1 ред за всяка ГРУПИРАНА стойност.
Нормалният проблем е, че хората искат друга колона за този ред. Например кажете, че всеки от редовете във вашите примерни данни също има IP адрес и искате този, който се равнява на най-високия идентификатор за ads_post_id:-
id | ads_post_id ip_address
---------------------------------------------------------------------------
22 | 983314845117571 192.168.0.0
23 | 983314845117571 192.168.0.5
24 | 983314845117571 192.168.0.7
104 | 983314845117571 192.168.0.0
250 | 983314845117571 192.168.0.4
253 | 983314845117571 192.168.0.6
767 | 983314845117571 192.168.0.1
---------------------------------------------------------------------------
В този случай не можете просто да използвате MAX. Например, ако сте опитали:-
SELECT ads_post_id, MAX(id), MAX(ip_address)
FROM fb_ads
GROUP BY ads_post_id
LIMIT 6
Ще получите следните върнати данни
id | ads_post_id ip_address
---------------------------------------------------------------------------
767 | 983314845117571 192.168.0.7
---------------------------------------------------------------------------
Ако опитате следното в повечето разновидности на SQL, ще получите грешка. В MySQL с настройките по подразбиране бихте получили резултат, но кой IP адрес се връща не е дефиниран (и всъщност произволен).
SELECT ads_post_id, MAX(id), ip_address
FROM fb_ads
GROUP BY ads_post_id
LIMIT 6
Решенията за това са или да получите максималния идентификатор за всеки ads_post_id в подзаявка и след това да го присъедините обратно към таблицата, за да получите останалите стойности:-
SELECT a.ads_post_id,
a.id,
a.ip_address
FROM fb_ads a
INNER JOIN
(
SELECT ads_post_id, MAX(id) AS max_id
FROM fb_ads
GROUP BY ads_post_id
) sub0
ON a.ads_post_id = sub0.ads_post_id
AND a.id = sub0.max_id
Алтернатива е (зло)използването на агрегатната функция GROUP_CONCAT. GROUP_CONCAT ще върне всички стойности, свързани заедно в 1 поле, всяко разделено с , (по подразбиране). Можете да добавите клауза ORDER BY, за да наложите реда, в който са свързани. Можете да използвате SUBSTRING_INDEX, за да върнете всичко до първата запетая.
Това може да бъде полезно за прости данни, но става проблематично с текстови данни или полета, които не повече от NULL.
SELECT a.ads_post_id,
SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY id DESC), ',', 1),
SUBSTRING_INDEX(GROUP_CONCAT(ip_address ORDER BY id DESC), ',', 1)
FROM fb_ads
GROUP BY ads_post_id