Sua solução utiliza uma extensão da cláusula GROUP BY que permite agrupar por alguns campos (neste caso, apenas post_author
):
GROUP BY wp_posts.post_author
e selecione colunas não agregadas:
SELECT wp_posts.*
que não estão listados no grupo por cláusula ou que não são usados em uma função agregada (MIN, MAX, COUNT, etc.).
Uso correto da extensão à cláusula GROUP BY
Isso é útil quando todos os valores de colunas não agregadas são iguais para cada linha.
Por exemplo, suponha que você tenha uma tabela GardensFlowers
( name
do jardim, flower
que cresce no jardim):
INSERT INTO GardensFlowers VALUES
('Central Park', 'Magnolia'),
('Hyde Park', 'Tulip'),
('Gardens By The Bay', 'Peony'),
('Gardens By The Bay', 'Cherry Blossom');
e você deseja extrair todas as flores que crescem em um jardim, onde várias flores crescem. Então você tem que usar uma subconsulta, por exemplo, você pode usar isto:
SELECT GardensFlowers.*
FROM GardensFlowers
WHERE name IN (SELECT name
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)>1);
Se você precisar extrair todas as flores que são as únicas no jardim, basta alterar a condição HAVING para HAVING COUNT(DISTINCT flower)=1
, mas o MySql também permite que você use isso:
SELECT GardensFlowers.*
FROM GardensFlowers
GROUP BY name
HAVING COUNT(DISTINCT flower)=1;
sem subconsulta, não SQL padrão, mas mais simples.
Uso incorreto da extensão à cláusula GROUP BY
Mas o que acontece se você selecionar colunas não agregadas que não são iguais para cada linha? Qual é o valor que o MySql escolhe para essa coluna?
Parece que o MySql sempre escolhe o PRIMEIRO valor que encontra.
Para garantir que o primeiro valor encontrado seja exatamente o valor desejado, aplique a GROUP BY
a uma consulta ordenada, daí a necessidade de usar uma subconsulta. Você não pode fazer isso de outra maneira.
Dado que o MySql sempre escolhe a primeira linha que encontra, você está classificando corretamente as linhas antes do GROUP BY. Infelizmente, se você ler atentamente a documentação, perceberá que essa suposição não é verdadeira.
Ao selecionar colunas não agregadas que nem sempre são iguais, o MySql é livre para escolher qualquer valor, portanto o valor resultante que ele realmente mostra é indeterminado .
Vejo que esse truque para obter o primeiro valor de uma coluna não agregada é muito usado, e geralmente / quase sempre funciona, eu também o uso às vezes (por meu próprio risco). Mas como não está documentado, você não pode confiar nesse comportamento.
Este link (obrigado ypercube!) O truque GROUP BY foi otimizado para longe, mostra uma situação em que a mesma consulta retorna resultados diferentes entre o MySql e o MariaDB, provavelmente por causa de um mecanismo de otimização diferente.
Portanto, se esse truque funcionar, é apenas uma questão de sorte.
A resposta aceita na outra pergunta parece errada para mim:
HAVING wp_posts.post_date = MAX(wp_posts.post_date)
wp_posts.post_date
é uma coluna não agregada e seu valor será oficialmente indeterminado, mas provavelmente será o primeiro post_date
encontrado. Porém, como o truque GROUP BY é aplicado a uma tabela não ordenada, não há certeza de qual é a primeira post_date
encontrada.
Provavelmente retornará postagens que são as únicas postagens de um único autor, mas mesmo isso nem sempre é certo.
Uma possível solução
Eu acho que isso poderia ser uma solução possível:
SELECT wp_posts.*
FROM wp_posts
WHERE id IN (
SELECT max(id)
FROM wp_posts
WHERE (post_author, post_date) = (
SELECT post_author, max(post_date)
FROM wp_posts
WHERE wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY post_author
) AND wp_posts.post_status='publish'
AND wp_posts.post_type='post'
GROUP BY post_author
)
Na consulta interna, estou retornando a data máxima de postagem para cada autor. Então, estou levando em consideração o fato de que o mesmo autor poderia teoricamente ter duas postagens ao mesmo tempo, então estou obtendo apenas o ID máximo. E então eu estou retornando todas as linhas que têm esses IDs máximos. Isso pode ser feito mais rapidamente usando junções em vez da cláusula IN.
(Se você tem certeza de que ID
está aumentando apenas e ID1 > ID2
também significa isso post_date1 > post_date2
, a consulta pode ser muito mais simples, mas não tenho certeza se esse é o caso).
post_author
epost_date
não são o suficiente para obter uma linha única, então tem que haver mais para obter uma linha única perpost_author