SQL按Group By分组并配合Order By排序

163
我有一个标签表格,想要从列表中获取计数最高的标签。
示例数据如下。
id (1) tag ('night')
id (2) tag ('awesome')
id (3) tag ('night')

使用

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

这个代码可以完美地获取我想要的数据。但是,我希望对它进行整理,使得标签计数最高的出现在前面,并且只发送前20个结果。

我尝试了以下代码...

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

我一直在遇到一个“无效的组函数使用 - ErrNr 1111”的错误。

我做错了什么?

我正在使用MySQL 4.1.25-Debian。

5个回答

243
在所有的MySQL版本中,只需要在SELECT列表中对聚合函数进行别名,并按照别名排序即可:
SELECT COUNT(id) AS theCount, `Tag` from `images-tags`
GROUP BY `Tag`
ORDER BY theCount DESC
LIMIT 20

10
在我看来,这个版本比所选答案更简洁。它立即清楚地表明了订购的内容。当然,如果这只是一个快速脚本,那就不太重要了。 - JustAPoring
1
尽管 OP 使用的是 MySQL,但这个答案在 HSQL(Libreoffice 内置)中也适用于我。 - Arno Teigseth

55

MySQL 5版本之前不允许在ORDER BY子句中使用聚合函数。

您可以通过使用已弃用的语法来规避此限制:

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

1,因为这是您想要进行分组的第一列。


13

我不了解MySQL,但在MS SQL中,您可以在order by子句中使用列索引。当进行带有group by的计数时,我曾经这样做过,因为它通常更容易处理。

所以:

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

变为

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

9
在Oracle中,类似这样的方法可以很好地将计数和排序分开。我不确定它是否适用于MySQL 4。
select 'Tag', counts.cnt
from
  (
  select count(*) as cnt, 'Tag'
  from 'images-tags'
  group by 'tag'
  ) counts
order by counts.cnt desc

在10.1.14-MariaDB(兼容MySQL)中对我有效。我以为必须要有“) as counts”,但没有“as”部分仍然可以工作。 - Harry Pehkonen

-4

尝试一下这个查询

 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

1
这与问题有什么关系?这些字段甚至都不一样。 - Blakes Seven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接