SELECT select_expression, select_expression, ... GROUP BY groupby_expression [, groupby_expression, ...]
复制
GROUP BY子句将查询结果按列值并组,也就是指定列列值相同的将被并入同组。
GROUP BY常常与聚合函数合用—— 将查询结果按列值并组,然后再对每组分别使用聚合函数。 更多关于聚合函数的内容请参考“函数和运算符”下的“聚合函数”章节。
注意:使用GROUP BY时,SELECT语句和GROUP BY子句所包含的列必须相同。
语法
说明
-
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"小节。