联 系 我 们
售前咨询
售后咨询
微信关注:星环科技服务号
更多联系方式 >
6.4.4 GROUP BY
更新时间:4/8/2024, 12:15:03 PM

GROUP BY子句将查询结果按列值并组,也就是指定列列值相同的将被并入同组。

GROUP BY常常与聚合函数合用—— 将查询结果按列值并组,然后再对每组分别使用聚合函数。 更多关于聚合函数的内容请参考“函数和运算符”下的“聚合函数”章节。

注意:使用GROUP BY时,SELECT语句和GROUP BY子句所包含的列必须相同。

语法

SELECT select_expression, select_expression, ...
GROUP BY groupby_expression [, groupby_expression, ...]
复制

说明

  • select_expression可以是列,表达式,也可以是聚合函数。

  • groupby_expression可以是列,也可以是表达式

单列GROUP BY

单列GROUP BY就是GROUP BY 子句中只有一列。

举例 我们可以用对transactions表用GROUP BY查看各个账户进行交易的次数:

SELECT acc_num, COUNT(trans_id) AS cnt
FROM transactions  
GROUP BY acc_num;
复制
acc_num cnt

3912384

4

6670192

2

2394923

1

2755506

1

6513065

6

0700735

3

5224133

2

6600641

1

但是,如果我们想要查看各个账户所有交易的流水号(trans_id),我们不能使用GROUP BY:

无效代码

SELECT acc_num, trans_id 
FROM transactions 
GROUP BY acc_num;
复制
COMPILE FAILED: Semantic error: [Error 10025] Line 1:16 Expression not in GROUP BY key. Error encountered near token 'trans_id'
复制

上面这段代码是无效的,因为SELECT语句中包含了列trans_id,但是trans_id不包含在GROUP BY子句中。我们看到6513065这个账号进行了6次交易,上面查询要Timelyre为6513065返回一个trans_id值,但是Timelyre不知道应该返回哪一个trans_id,故Timelyre会报错。

举例

下面代码查看进行了买(b)和卖(s)操作的账户个数。

SELECT trans_type, COUNT(DISTINCT acc_num) AS cnt
FROM transactions 
GROUP BY trans_type;
复制
trans_type cnt

b

4

s

8

有4个账户进行了买操作,有8个账户进行了卖操作。注意,count(DISTINCT acc_num)中的DISTINCT确保在统计账户个数时,一个acc_num仅统计一次。

注意: 一次查询可以使用多个聚合函数,但是聚合函数的参数中的DISTINCT列必须相同。

GROUP BY (number)
  • 语法:

    SELECT select_expression1, select_expression2, ...GROUP BY groupby_expression [, groupby_expression, ...]
    复制

    Timelyre中支持group by 1 (第一列),group by 2(第二列)这类用法,其中数字1是指select_expression的位置。

  • 利用 group by 语句查看test1中Num列也就是第一列每一个数字对应的字母的个数。

    SELECT * FROM test1;
    复制
    num letter

    1

    a

    1

    b

    1

    c

    1

    d

    2

    a

    2

    b

    2

    c

    3

    e

    3

    f

    4

    g

    5

    h

    6

    i

  • 利用 group by 语句查看test1中Num列也就是第一列每一个数字对应的字母的个数

    SELECT num, COUNT(letter) AS cnt
    FROM test1 
    GROUP BY num;
    复制
    num cnt

    4

    1

    1

    4

    5

    1

    2

    3

    6

    1

    3

    2

  • 我们可以把上例中的 'num’换成'1',来查看第一列每一个数字对应的字母的个数。

    SELECT num, COUNT(letter) AS cnt
    FROM test1 
    GROUP BY 1;
    复制
    num cnt

    4

    1

    1

    4

    5

    1

    2

    3

    6

    1

    3

    2

  • 利用 group by 语句查看test1中letter列也就是第二列每一个字母对应的数字的个数。

    SELECT letter,COUNT(num) AS cnt
    FROM test1 
    GROUP BY letter;
    复制
    letter cnt

    d

    1

    h

    1

    a

    2

    i

    1

    e

    1

    b

    2

    f

    1

    c

    2

    g

    1

  • 我们可以把上例中的 'letter’换成'2',来查看第二列每一个字母对应的数字的个数。

    SELECT COUNT(num) AS cnt, letter 
    FROM test1 
    GROUP BY 2;
    复制
    cnt letter

    1

    h

    1

    d

    2

    a

    1

    i

    1

    e

    2

    b

    1

    f

    1

    g

    2

    c

多列GROUP BY

多列GROUP BY就是GROUP BY子句中有不止一列。

举例

下例查询各账户进行的买和卖交易各有多少笔:

SELECT acc_num, trans_type, COUNT(trans_id) AS cnt
FROM transactions 
GROUP BY acc_num, trans_type;
复制
acc_num trans_type cnt

6513065

b

4

0700735

b

1

5224133

b

1

6600641

s

1

6513065

s

2

5224133

s

1

2755506

s

1

0700735

s

2

2394923

s

1

3912384

b

2

6670192

s

2

3912384

s

2

用表达式GROUP BY

举例

下例查询2014年各个月份中发生的交易数量。tdh_todate是Timelyre自带的函数,可以用来提取trans_time中的月份:

SELECT tdh_todate(datatime, 'yyyy-MM-dd HH:mm:ss', 'MM') AS month, count(*) AS num
FROM t_msis_aws_min_2
GROUP BY month;
复制
month num

03

8

在GROUP BY子句中过滤:HAVING 子句

详见"5.4.2. 过滤:WHERE和HAVING"小节。