MySQL 中所有行的计数总和 (*)

sum of count(*) for all rows in MySQL

我被 sum() 查询困住了,我想要 group by.

的所有行中的 count(*) 值的总和

这里是查询:

select
    u.user_type as user,
    u.count,
    sum(u.count)
FROM
(
select 
    DISTINCT
    user_type,
    count(*) as count
FROM
    users
where
    (user_type = "driver" OR user_type = "passenger")
GROUP BY
    user_type
) u;

当前输出:

----------------------------------
|  user     |  count     |  sum  |
----------------------------------
| driver    | 58         |  90   |
----------------------------------

预期输出:

----------------------------------
|  user     |  count     |  sum  |
----------------------------------
| driver    | 58         |  90   |
| passenger | 32         |  90   |
----------------------------------

如果我从查询中删除 sum(u.count),则输出如下所示:

--------------------------
|  user     |  count     |
--------------------------
| driver    | 58         |
| passenger | 32         |
--------------------------

user-type的末尾添加一个group by子句,例如:

select
    u.user_type as user,
    u.count,
    sum(u.count)
FROM
(
select 
    DISTINCT
    user_type,
    count(*) as count
FROM
    users
where
    (user_type = "driver" OR user_type = "passenger")
GROUP BY
    user_type
) u GROUP BY u.user_type;

您需要一个子查询:

   SELECT user_type, 
          Count(*) AS count,
          (SELECT COUNT(*) 
           FROM users 
           WHERE user_type IN ("driver","passenger" )) as sum  
   FROM   users 
   WHERE  user_type IN ("driver","passenger" ) 
   GROUP  BY user_type ; 

请注意,这里不需要 distinct

   SELECT user_type, 
          Count(*) AS count,
          c.sum
   FROM   users 
   CROSS JOIN ( 
           SELECT COUNT(*) as sum
           FROM users 
           WHERE user_type IN ("driver","passenger" )
         ) as c

   WHERE  user_type IN ("driver","passenger" ) 
   GROUP  BY user_type ; 
select
    u.user_type as user,
    u.count,
    sum(u.count)
FROM users group by user

试试这个。内联视图获取总计:

SELECT a.user_type, 
       count(*) AS count,
       b.sum  
FROM   users a
JOIN (SELECT COUNT(*) as sum 
      FROM users 
      WHERE user_type IN ("driver","passenger" )
     ) b ON TRUE
WHERE  a.user_type IN ("driver","passenger" ) 
GROUP  BY a.user_type;

我很想问; 您确定在数据库级别需要这个吗?

除非您纯粹在数据库层工作,否则对这些结果的任何处理都将内置到应用程序层中,并且可能需要某种形式的循环遍历结果

运行

它可以更容易、更简单、更易读
  SELECT user_type,
         COUNT(*) AS count
    FROM users
   WHERE user_type IN ("driver", "passenger")
GROUP BY user_type

.. 简单的把应用层的总数加起来

正如 Juan 在另一个答案中指出的那样,DISTINCT 是多余的,因为 GROUP BY 确保每个结果行都是不同的

与 Juan 一样,对于 user_type,我也更喜欢在此处使用 IN 而不是 OR 条件,因为我发现它更具可读性。如果将来结合进一步的 AND 条件,它还可以减少混淆的可能性

顺便说一句,我会考虑将用户类型的名称 "driver" 和 "passenger" 移动到单独的 user_types table 中并通过您的用户的 ID 列 table

N.B. 如果您在数据库级别确实需要这个,我会提倡使用 Paul 的优秀选项之一,或者 Tom 提供的 CROSS JOIN 方法Mac,并由 Juan 作为他的第二个建议解决方案

您可以使用 WITH ROLLUP modifier:

select coalesce(user_type, 'total') as user, count(*) as count
from users
where user_type in ('driver', 'passenger')
group by user_type with rollup

这将 return 相同的信息,但格式不同:

user      | count
----------|------
driver    |    32
passenger |    58
total     |    90

db-fiddle

在 MySQL 8 中你可以使用 COUNT() 作为 window function:

select distinct
  user_type,
  count(*) over (partition by user_type) as count,
  count(*) over () as sum
from users
where user_type in ('driver', 'passenger');

结果:

user_type | count | sum
----------|-------|----
driver    |    32 |  90
passenger |    58 |  90

db-fiddle

或使用CTE (Common Table Expressions):

with cte as (
  select user_type, count(*) as count
  from users
  where user_type in ('driver', 'passenger')
  group by user_type
)
select user_type, count, (select sum(count) from cte) as sum
from cte

db-fiddle

您可以简单地将 SUM() OVER()COUNT(*) 结合使用:

SELECT user_type, COUNT(*) AS cnt, SUM(COUNT(*)) OVER() AS total
FROM  users WHERE user_type IN ('driver', 'passenger') GROUP BY user_type;

db<>fiddle demo


输出:

+------------+------+-------+
| user_type  | cnt  | total |
+------------+------+-------+
| passenger  |  58  |    90 |
| driver     |  32  |    90 |
+------------+------+-------+

Tom Mac 正确解释你的答案。这是您可以执行此操作的另一种方法。 我检查了查询性能,在 1000 条记录中没有发现任何差异

   select user_type,Countuser,(SELECT COUNT(*) 
   FROM users 
   WHERE user_type IN ('driver','passenger ') )as sum from (
   select user_type,count(*) as Countuser from users a
   where a.user_type='driver'
   group by a.user_type
   union
   select user_type,count(*) as Countuser from users b
   where b.user_type='passenger'
   group by b.user_type
   )c
   group by user_type,Countuser

试试这个:

WITH SUB_Q AS (
  SELECT USER_TYPE, COUNT (*) AS CNT
  FROM USERS
  WHERE USER_TYPE = "passenger" OR USER_TYPE = "driver"
  GROUP BY USER_TYPE
), 
SUB_Q2 AS (
  SELECT SUM(CNT) AS SUM_OF_COUNT
  FROM SUB_Q
)
SELECT A.USER_TYPE, A.CNT AS COUNT, SUB_Q2 AS SUM
FROM SUB_Q JOIN SUB_Q2 ON (TRUE);

我使用了 postgresql 方言,但您可以轻松更改为子查询。