如何将 COUNT 与多列一起使用?

and*_*ndy 10 mysql count

如何在单个 COUNT 中使用多列?

假设有一个demo包含这些数据的表:

id |  col1  |  col2  |    
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*  
1  |'alice' | 'book1'|  
2  |'bob'   | 'book1'|  
3  |'alice' | 'book2'|  
4  |'alice' | 'book3'|
Run Code Online (Sandbox Code Playgroud)

我想找到用户和书名的所有组合的计数。

我试过,如果我运行distinct,一切都很好。
select count(distinct col1, col2) from demo

但是,当我删除时distinct,sql 语句将不会在 mysql 控制台中传递。
select count(col1, col2) from demo

问题是如何COUNT在 MySql 中使用多列?

ype*_*eᵀᴹ 9

你可以用COUNT()函数来计算几件事:

  • count(*) : 行
  • count(col1):col1不为空的行
  • count(col2):col2不为空的行
  • count(distinct col1): 不同的col1价值观。
  • count(distinct col2): 不同的col2价值观。
  • count(distinct col1, col2): 不同的(col1, col2)值组合。

SQLfiddle测试:

    select 
        count(*)             as count_rows,
        count(col1)          as count_1,
        count(col2)          as count_2,
        count(distinct col1) as count_distinct_1,
        count(distinct col2) as count_distinct_2,
        count(distinct col1, col2) as count_distinct_1_2
    from demo ;
Run Code Online (Sandbox Code Playgroud)

count(col1, col2)不是有效的语法:

select 
    count(col1, col2) 
from demo ;
Run Code Online (Sandbox Code Playgroud)

给出一个错误:

您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取'col2) from demo'在第 2 行附近使用的正确语法。

  • 没有文档 == 无效。 (2认同)

And*_*y M 5

显然,COUNT(DISTINCT)多列计算指定列值的唯一组合。然而,另一个重要的一点是,只有当元组中的任何单个值都不为空时,才会对元组进行计数。如果行为的最后一个方面是您要实现的目标,则可以使用条件 inside 来模拟它COUNT。它可以是符合标准的CASE

SELECT
  COUNT(CASE WHEN col1 IS NOT NULL AND col2 IS NOT NULL THEN 1 END)
FROM
  demo
;
Run Code Online (Sandbox Code Playgroud)

或特定于 MySQL 的IF函数:

SELECT
  COUNT(IF(col1 IS NOT NULL AND col2 IS NOT NULL, 1, NULL))
FROM
  demo
;
Run Code Online (Sandbox Code Playgroud)

1您可以在其中放置任何非空常量而不是您。仅当既不col1也不col2为空时,才会计算一行。

这种解决方法(任一变体)的明显缺陷是它显然相当笨拙,并且随着您添加更多列来考虑,它会很快变得可笑。

可以通过选择不太清晰的语法来稍微缩短表达式。特别是,您可以替换COUNTwithSUM并将谓词视为算术表达式中的数字 (1/0):

SELECT
  SUM( (col1 IS NOT NULL) * (col2 IS NOT NULL) )
FROM
  demo
;
Run Code Online (Sandbox Code Playgroud)

在算术运算符的上下文中,运算符*的逻辑结果IS NOT NULL被隐式转换为数字,1 表示真,0 表示假。只有 1 和 0 的*操作符相当于逻辑AND:只有当每个操作数为 1 时,最终结果才会为 1(真);否则结果将为 0 (False)。将 ( SUM) 1s 相加等于计算真值。

同样,上面的语句将只计算既不是空col1也不col2是空的行。

  • `SUM(col1 IS NOT NULL AND col2 IS NOT NULL)` 也应该可以工作,对吗? (2认同)