如何在同一个 select 语句中使用 count 和 group by

Posted

技术标签:

【中文标题】如何在同一个 select 语句中使用 count 和 group by【英文标题】:How to use count and group by at the same select statement 【发布时间】:2011-02-12 22:11:29 【问题描述】:

我有一个包含分组依据的 sql 选择查询。 我想统计分组后的所有记录。 有没有办法直接从sql中解决这个问题? 例如,有一张包含用户的表格,我想选择不同的城镇和用户数

select town, count(*) from user
group by town

我希望有一列包含所有城镇,另一列包含所有行中的用户数。

拥有 3 个城镇和 58 个用户的结果示例如下:

Town         Count
Copenhagen   58
NewYork      58
Athens       58

【问题讨论】:

你的意思是你希望你的结果集有 2 个计数,一个用于城镇,一个用于用户? 所以你希望每个城镇有一行,并且在每一行中,第 2 列包含所有用户的总数?那么第 2 列的每一行都有 same 值吗?如果您编辑以包含示例数据和所需的输出,我们将能够准确地为您提供您想要的。 相关问题:***.com/questions/5146978/… 读者注意:大多数答案无法为更新后的查询提供答案。 您的查询不正确吗? 【参考方案1】:

这将做你想做的(城镇列表,每个城镇的用户数量):

select town, count(town) 
from user
group by town

在使用GROUP BY时,你可以使用大多数aggregate functions:

COUNTMAXCOUNT DISTINCT 等)

更新(在问题和 cmets 更改后)

您可以为用户数声明一个变量并将其设置为用户数,然后使用它进行选择。

DECLARE @numOfUsers INT
SET @numOfUsers = SELECT COUNT(*) FROM user

SELECT DISTINCT town, @numOfUsers
FROM user

【讨论】:

这正是 OP 写的? nvm,我看到了你的不同,你指的是 Town 而不是 *.... @Leslie - 这两个查询没有区别。它们将返回相同的结果集。我只是不喜欢使用*... OP 回答了他自己的问题,但似乎甚至没有测试它,我只是在验证它是正确的:) fredosaurus.com/notes-db/select/groupby.html 再次不是我所希望的,但似乎这是最好的解决方案.. ;) 谢谢【参考方案2】:

你可以使用COUNT(DISTINCT ...)

SELECT COUNT(DISTINCT town) 
FROM user

【讨论】:

作为一种魅力...应该选择主要答案..除了一些调查认为这不好。 我认为他们的意思是如果你把 COUNT(DISTINCT town) 放在 WHERE 子句中。那是因为它是一个聚合函数,需要在 HAVING 子句中提供。此 SQL 查询对某些人具有误导性,因为 SELECT COUNT(DISTINCT town) 变成了隐式 GROUP BY,由于 COUNT 和 DISTINCT 关键字,每个关键字本身也会隐式分组。 谢谢。点赞。正是需要的 - 在一个操作中分组 + 计数并在结果中获得单行。 @milkovsky - 不,您不必删除它。我只是觉得这个问题加上许多答案已经分成解决两个不同问题,这让我很恼火。您的答案在两个方面有所不同——没有town 列,它COUNTs 是错误的(城镇而不是用户)。 @rogerdpack COUNT(DISTINCT ...)GROUP BY 一起使用,只需确保您的分组字段出现在SELECT 语句中。示例:SELECT COUNT(DISTINCT town), street FROM user GROUP BY street【参考方案3】:

另一种方式是:

/* Number of rows in a derived table called d1. */
select count(*) from
(
  /* Number of times each town appears in user. */
  select town, count(*)
  from user
  group by town
) d1

【讨论】:

需要别名,否则在 mysql 中不起作用。 select count(*) from( ) agr【参考方案4】:

十个未删除的答案;大多数做用户要求的事情。大多数答案将问题误读为认为每个镇有 58 个用户,而不是总共 58 个用户。即使是少数正确的也不是最优的。

mysql> flush status;
Query OK, 0 rows affected (0.00 sec)

SELECT  province, total_cities
    FROM       ( SELECT  DISTINCT province  FROM  canada ) AS provinces
    CROSS JOIN ( SELECT  COUNT(*) total_cities  FROM  canada ) AS tot;
+---------------------------+--------------+
| province                  | total_cities |
+---------------------------+--------------+
| Alberta                   |         5484 |
| British Columbia          |         5484 |
| Manitoba                  |         5484 |
| New Brunswick             |         5484 |
| Newfoundland and Labrador |         5484 |
| Northwest Territories     |         5484 |
| Nova Scotia               |         5484 |
| Nunavut                   |         5484 |
| Ontario                   |         5484 |
| Prince Edward Island      |         5484 |
| Quebec                    |         5484 |
| Saskatchewan              |         5484 |
| Yukon                     |         5484 |
+---------------------------+--------------+
13 rows in set (0.01 sec)

SHOW session status LIKE 'Handler%';

+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_commit             | 1     |
| Handler_delete             | 0     |
| Handler_discover           | 0     |
| Handler_external_lock      | 4     |
| Handler_mrr_init           | 0     |
| Handler_prepare            | 0     |
| Handler_read_first         | 3     |
| Handler_read_key           | 16    |
| Handler_read_last          | 1     |
| Handler_read_next          | 5484  |  -- One table scan to get COUNT(*)
| Handler_read_prev          | 0     |
| Handler_read_rnd           | 0     |
| Handler_read_rnd_next      | 15    |
| Handler_rollback           | 0     |
| Handler_savepoint          | 0     |
| Handler_savepoint_rollback | 0     |
| Handler_update             | 0     |
| Handler_write              | 14    |  -- leapfrog through index to find provinces  
+----------------------------+-------+

在 OP 的上下文中:

SELECT  town, total_users
    FROM       ( SELECT  DISTINCT town  FROM  canada ) AS towns
    CROSS JOIN ( SELECT  COUNT(*) total_users  FROM  canada ) AS tot;

由于tot 中只有一行,CROSS JOIN 不会像其他情况下那样庞大。

通常的模式是COUNT(*),而不是COUNT(town)。后者意味着检查 town 是否不为空,这在这种情况下是不必要的。

【讨论】:

“通常的模式是 COUNT(*) 而不是 COUNT(town)。后者意味着检查 town 是否不为空,这在这种情况下是不必要的”谢谢你实际上提到,有很难弄清楚差异!【参考方案5】:

借助 Oracle,您可以使用分析函数:

select town, count(town), sum(count(town)) over () total_count from user
group by town

您的其他选择是使用子查询:

select town, count(town), (select count(town) from user) as total_count from user
group by town

【讨论】:

类似最后一个的方法会起作用,但我想看看是否有其他解决方案.. 你不能使用第一个(分析函数)选项吗?您使用的是什么数据库平台? @Stavros:最后一个很慢【参考方案6】:

如果您想按数量排序(听起来很简单,但我无法在堆栈上找到如何做到这一点的答案),您可以这样做:

        SELECT town, count(town) as total FROM user
        GROUP BY town ORDER BY total DESC

【讨论】:

【参考方案7】:

你可以像 Milkovsky 所说的那样在 COUNT 中使用 DISTINCT

就我而言:

select COUNT(distinct user_id) from answers_votes where answer_id in (694,695);

这将拉取被认为与 user_id 相同的答案票数

【讨论】:

【参考方案8】:

我知道这是一篇旧帖子,在 SQL Server 中:

select  isnull(town,'TOTAL') Town, count(*) cnt
from    user
group by town WITH ROLLUP

Town         cnt
Copenhagen   58
NewYork      58
Athens       58
TOTAL        174

【讨论】:

回复旧帖没有错。但是,请包括对您的代码以及代码本身的解释。 MySQL 等效项(IFNULL 而不是ISNULL)导致每个城镇的数字不同;用户想要总数。根据问题,总数是 58,而不是 174。【参考方案9】:

如果要选择城镇和总用户数,可以使用以下查询:

SELECT Town, (SELECT Count(*) FROM User) `Count` FROM user GROUP BY Town;

【讨论】:

这假设(也许是合理的)User 中没有重复的“用户”。【参考方案10】:

如果您想使用带计数选项的全选查询,试试这个...

 select a.*, (Select count(b.name) from table_name as b where Condition) as totCount from table_name  as a where where Condition

【讨论】:

感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。一个正确的解释would greatly improve 它的长期价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。【参考方案11】:

试试下面的代码:

select ccode, count(empno) 
from company_details 
group by ccode;

【讨论】:

我们使用此代码来查找每个 ccode(公司代码)中当前 calc 的总员工人数:对于 ccode 1,count(empno) 为 1839,对于 ccode 1,count(empno) 为 9421 ccode 47.

以上是关于如何在同一个 select 语句中使用 count 和 group by的主要内容,如果未能解决你的问题,请参考以下文章

如何在select语句中获取第一列的计数

在SELECT中使用count(*)over(…)语句中的计算列

select count函数怎么用

不就是SELECT COUNT语句吗,居然有这么多学问

为啥 SQL SELECT 语句在 Java Spring boot 项目中不返回 COUNT() 结果?

为啥将 count(*) 添加到 select 语句会强制行存在于子查询中?