Agrupar por com um pedido por

122

Eu tenho uma tabela de tags e quero obter as tags de contagem mais alta da lista.

Os dados de amostra têm esta aparência

id (1) tag ('night')
id (2) tag ('awesome')
id (3) tag ('night')

usando

SELECT COUNT(*), `Tag` from `images-tags`
GROUP BY `Tag`

retorna os dados que estou procurando perfeitamente. No entanto, eu gostaria de organizá-lo, para que as contagens mais altas de tags sejam as primeiras e limitá-las a enviar apenas os primeiros 20 ou mais.

Eu tentei isso ...

SELECT COUNT(id), `Tag` from `images-tags`
GROUP BY `Tag`
ORDER BY COUNT(id) DESC
LIMIT 20

e continuo recebendo uma "Uso inválido da função de grupo - Erro 1111"

O que estou fazendo de errado?

Estou usando o MySQL 4.1.25-Debian

maxsilver
fonte

Respostas:

199

Em todas as versões do MySQL, simplesmente alias o agregado na lista SELECT e ordene pelo alias:

SELECT COUNT(id) AS theCount, `Tag` from `images-tags`
GROUP BY `Tag`
ORDER BY theCount DESC
LIMIT 20
Scott Noyes
fonte
9
IMHO, esta é a versão mais limpa que a resposta selecionada. É instantaneamente claro o que é solicitado por. Claro, se é um roteiro rápido, isso realmente não importa.
JustAPoring
1
Embora OP está usando MySQL, esta resposta também trabalhou para mim em HSQL (interna do LibreOffice)
Arno Teigseth
53

O MySQL anterior à versão 5 não permitia funções agregadas nas cláusulas ORDER BY.

Você pode contornar esse limite com a sintaxe descontinuada:

SELECT COUNT(id), `Tag` from `images-tags`
GROUP BY `Tag`
ORDER BY 1 DESC
LIMIT 20

1, já que é a primeira coluna na qual você deseja agrupar.

Lasse V. Karlsen
fonte
8

Eu não sei sobre MySQL, mas no MS SQL, você pode usar o índice da coluna na order bycláusula. Eu já fiz isso antes quando conta comgroup by s, pois tende a ser mais fácil trabalhar.

assim

SELECT COUNT(id), `Tag` from `images-tags`
GROUP BY `Tag`
ORDER BY COUNT(id) DESC
LIMIT 20

Torna-se

SELECT COUNT(id), `Tag` from `images-tags`
GROUP BY `Tag`
ORDER 1 DESC
LIMIT 20
jerhinesmith
fonte
6

No Oracle, algo assim funciona muito bem para separar sua contagem e a encomenda um pouco melhor. Não tenho certeza se funcionará no MySql 4.

select 'Tag', counts.cnt
from
  (
  select count(*) as cnt, 'Tag'
  from 'images-tags'
  group by 'tag'
  ) counts
order by counts.cnt desc
JosephStyons
fonte
Parece funcionar para mim no 10.1.14-MariaDB (compatível com MySQL). Eu pensei que tinha que ter ) as counts, mas ainda funcionava sem a asparte.
Harry Pehkonen
3

Você pode contornar esse limite com a sintaxe descontinuada: ORDER BY 1 DESC

Essa sintaxe não está obsoleta, é E121-03 do SQL99.

Damien B
fonte
5
Este deve ser um comentário em vez de uma resposta.
Rafael Barros
0

Tente esta consulta

 SELECT  data_collector_id , count (data_collector_id ) as frequency 
    from rent_flats 
    where is_contact_person_landlord = 'True' 
    GROUP BY data_collector_id 
    ORDER BY count(data_collector_id) DESC
Ashutosh Gupta
fonte
O que isso tem a ver com a questão? Os campos não são iguais.
Blakes Seven