Špatně jste pochopili, jak GROUP BY funguje v SQL, kvůli funkci MySQL. Ve standardním SQL MUSÍ být každý neagregovaný sloupec v příkazu SELECT v klauzuli GROUP BY (existuje výjimka pro sloupce, jejichž hodnoty jsou 100% závislé na sloupci již v klauzuli GROUP BY, ačkoli tuto výjimku podporuje jen několik variant SQL) .
MySQL toto standardně nevynucuje, ale není definováno, které hodnoty řádků jsou pro tyto sloupce použity. I když můžete získat ten, který chcete, také nemusíte. A i když to uděláte, existuje šance, že se to v budoucnu změní.
Řazení je normálně nezávislé na GROUP BY, i když pokud neurčíte klauzuli ORDER, budou výsledky seřazeny podle toho, co bylo požadováno k provedení GROUPing (tj. pokud pomůže seřadit řádky v jednom pořadí, GROUP BY se pak MySQL nebude obtěžovat s přeuspořádáním záznamů poté, pokud mu to výslovně neřeknete pomocí klauzule ORDER BY).
Takže s vašimi aktuálními daty může být seskupení podle ads_post_id vrácená hodnota id 22, 23, 24, 104, 250, 253 nebo 767. Není definováno, který z nich se MySQL rozhodne použít.
S vaší aktuální opravou dat je to triviální, protože můžete získat pouze MAX id:-
SELECT ads_post_id, MAX(id)
FROM fb_ads
GROUP BY ads_post_id
LIMIT 6
MAX vrátí 1 řádek pro každou seskupenou hodnotu.
Normální problém je, že lidé chtějí pro tento řádek další sloupec. Řekněme například, že každý z řádků ve vašich ukázkových datech měl také IP adresu a chtěli jste tu, která se rovnala nejvyššímu id pro 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
---------------------------------------------------------------------------
V tomto případě nemůžete použít pouze MAX. Pokud jste například zkusili:-
SELECT ads_post_id, MAX(id), MAX(ip_address)
FROM fb_ads
GROUP BY ads_post_id
LIMIT 6
Vrátili byste následující data
id | ads_post_id ip_address
---------------------------------------------------------------------------
767 | 983314845117571 192.168.0.7
---------------------------------------------------------------------------
Pokud byste vyzkoušeli následující ve většině variant SQL, dostanete chybu. V MySQL s výchozím nastavením byste dostali výsledek, ale vrácená IP adresa není definována (a ve skutečnosti náhodná).
SELECT ads_post_id, MAX(id), ip_address
FROM fb_ads
GROUP BY ads_post_id
LIMIT 6
Řešením je buď získat maximální id pro každý ads_post_id v dílčím dotazu a poté jej připojit zpět k tabulce, abyste získali zbytek hodnot:-
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
Alternativou je (ab)použití agregační funkce GROUP_CONCAT. GROUP_CONCAT vrátí všechny hodnoty spojené dohromady do 1 pole, každé oddělené , (ve výchozím nastavení). Můžete přidat klauzuli ORDER BY a vynutit tak pořadí, do kterého jsou zřetězeni. Pomocí SUBSTRING_INDEX můžete vrátit vše až po první čárku.
To může být užitečné pro jednoduchá data, ale stává se to problematické u textových dat nebo polí, která mají max. hodnotu 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