COUNT函数

COUNT函数用于计算记录数。

适用范围

  • 窗口函数只能出现在SELECT语句中。

  • 窗口函数中不能嵌套使用窗口函数和聚合函数。

  • 窗口函数不能和同级别的聚合函数一起使用。

命令格式

-- 计算记录数
BIGINT COUNT([DISTINCT|ALL] <colname>)

-- 计算窗口中的记录数
BIGINT COUNT(*) OVER ([partition_clause] [orderby_clause] [frame_clause])
BIGINT COUNT([DISTINCT] <expr>[,...]) OVER ([partition_clause] [orderby_clause] [frame_clause])

参数说明

  • DISTINCT|ALL:可选。表示在计数时是否去除重复记录,默认为ALL,即计算全部记录。如果指定DISTINCT,则只计算唯一值数量。

  • colname:必填。列值可以为任意类型。colname可以为*,即COUNT(*),此时返回所有行数。colname值为NULL时,该行不参与计算。

  • expr:必填。待计算计数值的列。可以为任意类型。当值为NULL时,该行不参与计算。当指定DISTINCT关键字时,表示取唯一值的计数值。

    COUNT([DISTINCT] <expr>[,...]):计算指定窗口记录中所有值均不为NULL的行数。若指定DISTINCT关键字,则对这些行去重后计数。

  • partition_clauseorderby_clauseframe_clause:详情请参见windowing_definition

返回值说明

返回BIGINT类型。colname值为NULL时,该行不参与计算。

使用示例

准备测试数据

如果已有数据,可忽略该步骤。

  1. 下载测试数据test_data.txt

  2. 创建测试表

    CREATE TABLE IF NOT EXISTS emp(
      empno BIGINT,
      ename STRING,
      job STRING,
      mgr BIGINT,
      hiredate DATETIME,
      sal BIGINT,
      comm BIGINT,
      deptno BIGINT
    );
  3. 加载数据

    根据数据文件的实际path(路径以及名称)替换FILE_PATH

    TUNNEL UPLOAD FILE_PATH emp;   

示例1:指定某一列为开窗列,返回不排序情况下累计计数值

指定薪水(sal)为开窗列,不排序,返回当前窗口(相同sal)的从开始行到最后一行的累计计数值。

  • 命令示例

    SELECT sal, COUNT(sal) OVER (PARTITION BY sal) AS count FROM emp;
  • 返回结果

    +------------+------------+
    | sal        | count      | 
    +------------+------------+
    | 800        | 1          | 
    | 950        | 1          | 
    | 1100       | 1          | 
    | 1250       | 2          |  -- 窗口开始行。第1行和第2行的sal一致,则第1行的count为第2行的累计计数值。
    | 1250       | 2          |  -- 当前窗口从第1行到第2行的累计计数值。
    | 1300       | 2          | 
    | 1300       | 2          | 
    | 1500       | 1          | 
    | 1600       | 1          | 
    | 2450       | 2          | 
    | 2450       | 2          | 
    | 2850       | 1          | 
    | 2975       | 1          | 
    | 3000       | 2          | 
    | 3000       | 2          | 
    | 5000       | 2          | 
    | 5000       | 2          | 
    +------------+------------+

示例2:非Hive兼容模式下,指定某一列为开窗列,返回排序后累计计数值

Hive兼容模式下,指定薪水(sal)为开窗列,并排序,返回当前窗口(相同sal)从开始行到当前行的累计计数值。

  • 命令示例

    -- 关闭Hive兼容模式。
    SET odps.sql.hive.compatible=false;
    
    SELECT sal, COUNT(sal) OVER (PARTITION BY sal ORDER BY sal) AS count FROM emp;
  • 返回结果

    +------------+------------+
    | sal        | count      |
    +------------+------------+
    | 800        | 1          |
    | 950        | 1          |
    | 1100       | 1          |
    | 1250       | 1          |   -- 窗口开始行。第1行的累计计数值是1。
    | 1250       | 2          |   -- 第2行的累计计数值是2。
    | 1300       | 1          |
    | 1300       | 2          |
    | 1500       | 1          |
    | 1600       | 1          |
    | 2450       | 1          |
    | 2450       | 2          |
    | 2850       | 1          |
    | 2975       | 1          |
    | 3000       | 1          |
    | 3000       | 2          |
    | 5000       | 1          |
    | 5000       | 2          |
    +------------+------------+

示例3:Hive兼容模式下,指定某一列为开窗列,返回排序后累计计数值

Hive兼容模式下,指定薪水(sal)为开窗列,并排序,返回当前窗口(相同sal)从开始行至最后一行的累计计数值。

  • 命令示例

    -- 开启Hive兼容模式。
    SET odps.sql.hive.compatible=true;
    
    SELECT sal, COUNT(sal) OVER (PARTITION BY sal ORDER BY sal) AS count FROM emp; 
  • 返回结果

    +------------+------------+
    | sal        | count      |
    +------------+------------+
    | 800        | 1          |
    | 950        | 1          |
    | 1100       | 1          |
    | 1250       | 2          |   -- 窗口开始行。第1行和第2行的sal一致,则第1行的count为第2行的累计计数值。
    | 1250       | 2          |   -- 当前窗口从第1行到第2行的累计计数值。
    | 1300       | 2          |
    | 1300       | 2          |
    | 1500       | 1          |
    | 1600       | 1          |
    | 2450       | 2          |
    | 2450       | 2          |
    | 2850       | 1          |
    | 2975       | 1          |
    | 3000       | 2          |
    | 3000       | 2          |
    | 5000       | 2          |
    | 5000       | 2          |
    +------------+------------+

示例4:返回总行数

计算所有部门的总职工人数。

  • 命令示例

    SELECT COUNT(*) FROM emp;
  • 返回结果

    +------------+
    | _c0        |
    +------------+
    | 17         |
    +------------+

示例5:分组计算各组总数

GROUP BY配合使用,对所有职工按照部门(deptno)分组,计算各部门(deptno)的职工人数。

  • 命令示例

    SELECT deptno, COUNT(*) FROM emp GROUP BY deptno;
  • 返回结果

    +------------+------------+
    | deptno     | _c1        | 
    +------------+------------+
    | 20         | 5          | 
    | 30         | 6          | 
    | 10         | 6          | 
    +------------+------------+

示例6:去重计数

通过DISTINCT去重,计算部门数量。

  • 命令示例

    SELECT COUNT(DISTINCT deptno) FROM emp;
  • 返回结果

    +------------+
    | _c0        |
    +------------+
    | 3          |
    +------------+

相关函数

COUNT函数属于聚合函数或窗口函数。

  • 更多将多条输入记录进行求平均值、参数聚合的相关函数请参见聚合函数

  • 更多对指定开窗列的数据进行求和、数值排序的相关函数请参见窗口函数