ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

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

Town         Count
Copenhagen   58
NewYork      58
Athens       58
你的意思是你希望你的结果集有 2 个计数,一个用于城镇,一个用于用户?
因此,您希望每个城镇有一行,并且在每一行中,第 2 列包含所有用户的总数?那么第 2 列对每一行都有相同的值吗?如果您编辑以包含示例数据和所需的输出,我们将能够准确地为您提供您想要的。
对读者的警告:大多数答案未能为更新后的查询提供答案。
你的查询不正确吗?

r
rogerdpack

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

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

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

COUNTMAXCOUNT DISTINCT 等)

更新(在更改问题和评论之后)

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

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
再次不是我所希望的,但似乎这是最好的解决方案.. ;) 谢谢
m
milkovsky

您可以使用 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
K
Kamil Slowikowski

另一种方式是:

/* 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
R
Rick James

十个未删除的答案;大多数人不做用户要求的事情。大多数答案误读了这个问题,认为每个城镇有 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 是否不为空,这在这种情况下是不必要的”感谢您实际提及这一点,很难弄清楚差异!
T
Tommi

使用 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:最后一个很慢
R
Renato Probst

如果您想按计数订购(听起来很简单,但我在堆栈上找不到如何做到这一点的答案),您可以这样做:

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

J
Jur P

您可以在 COUNT 中使用 DISTINCT,就像 Milkovsky 所说的那样

就我而言:

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

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


M
Marcus

我知道这是 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。
S
Sal00m

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

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

这假设(也许是合理的)User 中没有重复的“用户”。
P
Prakash

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

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

感谢您提供此代码片段,它可能会提供一些有限的即时帮助。通过说明为什么这是一个很好的问题解决方案,正确解释would greatly improve它的长期价值,并使其对有其他类似问题的未来读者更有用。请edit您的回答以添加一些解释,包括您所做的假设。
J
JodyT

试试下面的代码:

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

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