Você não entendeu como o GROUP BY funciona no SQL, devido a um recurso do MySQL. No SQL padrão, toda coluna não agregada na instrução SELECT DEVE estar na cláusula GROUP BY (há uma exceção para colunas cujos valores são 100% dependentes de uma coluna já na cláusula GROUP BY, embora poucos tipos de SQL suportem essa isenção) .
O MySQL não impõe isso por padrão, mas quais valores de linhas são usados para essas colunas não são definidos. Embora você possa obter o que deseja, também pode não conseguir. E mesmo se você fizer isso, há uma chance de que isso mude no futuro.
A ordenação é independente do GROUP BY normalmente, embora se você não especificar uma cláusula ORDER, os resultados serão ordenados com base no que foi necessário para executar o GROUPing (ou seja, se ajudar a ordenar as linhas em uma ordem para fazer o GROUP BY então o MySQL não se incomodará em reordenar os registros posteriormente, a menos que você o diga especificamente com uma cláusula ORDER BY).
Assim, com seus dados atuais, agrupando por ads_post_id, o valor de id que é retornado pode ser 22, 23, 24, 104, 250, 253 ou 767. Qual MySQL escolhe usar não está definido.
Com sua correção de dados atual, isso é trivial, pois você pode obter o ID MAX:-
SELECT ads_post_id, MAX(id)
FROM fb_ads
GROUP BY ads_post_id
LIMIT 6
MAX retornará 1 linha para cada valor GROUPed.
O problema normal é que as pessoas querem outra coluna para essa linha. Por exemplo, digamos que cada uma das linhas em seus dados de exemplo também tenha um endereço IP e você queira aquele que equivale ao id mais alto para 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
---------------------------------------------------------------------------
Neste caso, você não pode simplesmente usar MAX. Por exemplo, se você tentou:-
SELECT ads_post_id, MAX(id), MAX(ip_address)
FROM fb_ads
GROUP BY ads_post_id
LIMIT 6
Você obteria os seguintes dados retornados
id | ads_post_id ip_address
---------------------------------------------------------------------------
767 | 983314845117571 192.168.0.7
---------------------------------------------------------------------------
Se você tentasse o seguinte na maioria dos tipos de SQL, obteria um erro. No MySQL com as configurações padrão, você obteria um resultado, mas qual endereço IP é retornado não é definido (e, na verdade, aleatório).
SELECT ads_post_id, MAX(id), ip_address
FROM fb_ads
GROUP BY ads_post_id
LIMIT 6
As soluções para isso são obter o id máximo para cada ads_post_id em uma subconsulta e, em seguida, juntá-lo de volta à tabela para obter o restante dos valores:-
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
Uma alternativa é (ab) usar a função agregada GROUP_CONCAT. GROUP_CONCAT trará de volta todos os valores concatenados em 1 campo, cada um separado por um , (por padrão). Você pode adicionar uma cláusula ORDER BY para forçar a ordem em que são concatenados. Você pode usar SUBSTRING_INDEX para retornar tudo até a primeira vírgula.
Isso pode ser útil para dados simples, mas se torna problemático com dados de texto ou campos que podem ser NULL no máximo.
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