如何在同一个 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:
(COUNT
、MAX
、COUNT 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中使用count(*)over(…)语句中的计算列