Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 110 additions & 2 deletions functions-and-operators/aggregate-group-by-functions.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: GROUP BY 聚合函数
aliases: ['/docs-cn/dev/functions-and-operators/aggregate-group-by-functions/','/docs-cn/dev/reference/sql/functions-and-operators/aggregate-group-by-functions/']
summary: TiDB支持的聚合函数包括 COUNT、COUNT(DISTINCT)、SUM、AVG、MAX、MIN、GROUP_CONCAT、VARIANCE、VAR_POP、STD、STDDEV、VAR_SAMP、STDDEV_SAMP 和 JSON_OBJECTAGG。除了 GROUP_CONCAT 和 APPROX_PERCENTILE 外,这些聚合函数可以作为窗口函数使用。另外,TiDB 的 GROUP BY 子句支持 WITH ROLLUP 修饰符,还支持 SQL 模式 ONLY_FULL_GROUP_BY。与 MySQL 的区别在于 TiDB 对标准 SQL 有一些扩展,允许在 HAVING 子句中使用别名和非列表达式。
summary: TiDB 支持的聚合函数包括 COUNT、COUNT(DISTINCT)、SUM、SUM_INT、MAX_COUNT、MIN_COUNT、AVG、MAX、MIN、GROUP_CONCAT、VARIANCE、VAR_POP、STD、STDDEV、VAR_SAMP、STDDEV_SAMP 和 JSON_OBJECTAGG。除了 GROUP_CONCAT、APPROX_PERCENTILEAPPROX_COUNT_DISTINCT 外,这些聚合函数可以作为窗口函数使用。另外,TiDB 的 GROUP BY 子句支持 WITH ROLLUP 修饰符,还支持 SQL 模式 ONLY_FULL_GROUP_BY。与 MySQL 的区别在于 TiDB 对标准 SQL 有一些扩展,允许在 HAVING 子句中使用别名和非列表达式。
---

# GROUP BY 聚合函数
Expand Down Expand Up @@ -35,6 +35,114 @@ TiDB 支持的 MySQL `GROUP BY` 聚合函数如下所示:

另外,TiDB 还支持以下聚合函数:

+ `SUM_INT(expr)`

该函数用于对整数表达式 `expr` 求和,功能类似于 `SUM(expr)`,但仅接受整数类型参数,包括有符号和无符号的 `TINYINT`、`SMALLINT`、`MEDIUMINT`、`INT` 和 `BIGINT`。对于有符号整数参数,返回类型为 `BIGINT`;对于无符号整数参数,返回类型为 `BIGINT UNSIGNED`。如果参与计算的非 `NULL` 值之和超出返回类型范围,TiDB 返回整数溢出错误。

`SUM_INT()` 忽略 `NULL` 值。如果没有非 `NULL` 值,返回 `NULL`。`SUM_INT()` 支持 `DISTINCT`,并可作为[窗口函数](/functions-and-operators/window-functions.md)使用。

以下是一个使用该函数的示例:

```sql
DROP TABLE IF EXISTS t;
CREATE TABLE t(id INT PRIMARY KEY, a BIGINT, b BIGINT UNSIGNED);
INSERT INTO t VALUES(1, 1, 1), (2, 1, 1), (3, 2, 2), (4, NULL, NULL);
```

```sql
SELECT SUM_INT(a), SUM_INT(DISTINCT a), SUM_INT(b) FROM t;
```

```sql
+------------+---------------------+------------+
| SUM_INT(a) | SUM_INT(DISTINCT a) | SUM_INT(b) |
+------------+---------------------+------------+
| 4 | 3 | 4 |
+------------+---------------------+------------+
1 row in set (0.00 sec)
```

以下示例将 `SUM_INT()` 作为窗口函数使用:

```sql
SELECT id, a, SUM_INT(a) OVER (ORDER BY id ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum
FROM t
ORDER BY id;
```

```sql
+----+------+-------------+
| id | a | rolling_sum |
+----+------+-------------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 3 |
| 4 | NULL | 2 |
+----+------+-------------+
4 rows in set (0.00 sec)
```

+ `MAX_COUNT([ALL] expr)` 和 `MIN_COUNT([ALL] expr)`

这两个函数是 TiDB 特有的聚合函数,用于统计组内最大值或最小值的出现次数。`MAX_COUNT(expr)` 返回 `expr` 的最大非 `NULL` 值在当前组中出现的行数;`MIN_COUNT(expr)` 返回 `expr` 的最小非 `NULL` 值在当前组中出现的行数。

这两个函数默认忽略 `NULL` 值。如果当前组中没有非 `NULL` 值,返回 `0`。返回类型为 `BIGINT`。这两个函数支持省略 `ALL` 或显式指定 `ALL`,但不支持 `DISTINCT`。例如,`MAX_COUNT(DISTINCT expr)` 和 `MIN_COUNT(DISTINCT expr)` 会返回语法错误。这两个函数也可作为[窗口函数](/functions-and-operators/window-functions.md)使用。

以下是一个使用这两个函数的示例:

```sql
DROP TABLE IF EXISTS t;
CREATE TABLE t(a INT);
INSERT INTO t VALUES(1), (1), (2), (2), (2), (NULL);
```

```sql
SELECT MAX_COUNT(a), MIN_COUNT(a) FROM t;
```

```sql
+--------------+--------------+
| MAX_COUNT(a) | MIN_COUNT(a) |
+--------------+--------------+
| 3 | 2 |
+--------------+--------------+
1 row in set (0.00 sec)
```

如果没有非 `NULL` 值,函数返回 `0`:

```sql
SELECT MAX_COUNT(a), MIN_COUNT(a) FROM t WHERE a IS NULL;
```

```sql
+--------------+--------------+
| MAX_COUNT(a) | MIN_COUNT(a) |
+--------------+--------------+
| 0 | 0 |
+--------------+--------------+
1 row in set (0.00 sec)
```

以下示例将 `MAX_COUNT()` 和 `MIN_COUNT()` 作为窗口函数使用:

```sql
SELECT
MAX_COUNT(a) OVER () AS max_count,
MIN_COUNT(a) OVER () AS min_count
FROM t
LIMIT 1;
```

```sql
+-----------+-----------+
| max_count | min_count |
+-----------+-----------+
| 3 | 2 |
+-----------+-----------+
1 row in set (0.00 sec)
```

+ `APPROX_PERCENTILE(expr, constant_integer_expr)`

该函数用于计算 `expr` 值的百分位数。参数 `constant_integer_expr` 是一个取值为区间 `[1,100]` 内整数的常量表达式,表示百分数。一个百分位数 P<sub>k</sub>(`k`为百分数)表示数据集中至少有 `k%` 的数据小于等于 P<sub>k</sub>。
Expand Down Expand Up @@ -88,7 +196,7 @@ TiDB 支持的 MySQL `GROUP BY` 聚合函数如下所示:
2 rows in set (0.00 sec)
```

上述聚合函数除 `GROUP_CONCAT()`、 `APPROX_PERCENTILE()` 和 `APPROX_COUNT_DISTINCT` 以外,均可作为[窗口函数](/functions-and-operators/window-functions.md)使用。
上述聚合函数除 `GROUP_CONCAT()`、`APPROX_PERCENTILE()` 和 `APPROX_COUNT_DISTINCT()` 以外,均可作为[窗口函数](/functions-and-operators/window-functions.md)使用。

## GROUP BY 修饰符

Expand Down
2 changes: 1 addition & 1 deletion functions-and-operators/expressions-pushed-down.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ TiFlash 也支持[本页](/tiflash/tiflash-supported-pushdown-calculations.md)
| [JSON 运算](/functions-and-operators/json-functions.md) | [JSON_ARRAY_APPEND()](/functions-and-operators/json-functions/json-functions-modify.md#json_array_append) <br/>[JSON_ARRAY()](/functions-and-operators/json-functions/json-functions-create.md#json_array) <br/>[JSON_CONTAINS()](/functions-and-operators/json-functions/json-functions-search.md#json_contains) <br/>[JSON_EXTRACT()](/functions-and-operators/json-functions/json-functions-search.md#json_extract) <br/>[JSON_INSERT()](/functions-and-operators/json-functions/json-functions-modify.md#json_insert) <br/>[JSON_LENGTH()](/functions-and-operators/json-functions/json-functions-return.md#json_length) <br/>[JSON_MERGE_PATCH()](/functions-and-operators/json-functions/json-functions-modify.md#json_merge_patch) <br/>[JSON_MERGE()](/functions-and-operators/json-functions/json-functions-modify.md#json_merge) <br/>[JSON_OBJECT()](/functions-and-operators/json-functions/json-functions-create.md#json_object) <br/>[JSON_REMOVE()](/functions-and-operators/json-functions/json-functions-modify.md#json_remove) <br/>[JSON_REPLACE()](/functions-and-operators/json-functions/json-functions-modify.md#json_replace) <br/>[JSON_SET()](/functions-and-operators/json-functions/json-functions-modify.md#json_set) <br/>[JSON_TYPE()](/functions-and-operators/json-functions/json-functions-return.md#json_type) <br/>[JSON_UNQUOTE()](/functions-and-operators/json-functions/json-functions-modify.md#json_unquote) <br/>[JSON_VALID()](/functions-and-operators/json-functions/json-functions-return.md#json_valid) <br/>[MEMBER OF()](/functions-and-operators/json-functions/json-functions-search.md#member-of) |
| [日期运算](/functions-and-operators/date-and-time-functions.md) | [DATE()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date) <br/>[DATE_FORMAT()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format) <br/>[DATEDIFF()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_datediff) <br/>[DAYOFMONTH()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_dayofmonth) <br/>[DAYOFWEEK()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_dayofweek) <br/>[DAYOFYEAR()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_dayofyear) <br/>[FROM_DAYS()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_from-days) <br/>[HOUR()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_hour) <br/>[MAKEDATE()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_makedate) <br/>[MAKETIME()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_maketime) <br/>[MICROSECOND()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_microsecond) <br/>[MINUTE()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_minute) <br/>[MONTH()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_month) <br/>[MONTHNAME()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_monthname) <br/>[PERIOD_ADD()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_period-add) <br/>[PERIOD_DIFF()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_period-diff) <br/>[SEC_TO_TIME()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_sec-to-time) <br/>[SECOND()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_second) <br/>[SYSDATE()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_sysdate) <br/>[TIME_TO_SEC()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_time-to-sec) <br/>[TIMEDIFF()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_timediff) <br/>[WEEK()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_week) <br/>[WEEKOFYEAR()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_weekofyear) <br/>[YEAR()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_year) <br/>[DATE_ADD()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-add) <br/>[DATE_SUB()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-sub) <br/>[ADDDATE()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_adddate) <br/>[SUBDATE()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_subdate) <br/>[FROM_UNIXTIME()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_from-unixtime) <br/>[TIMESTAMPDIFF()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_timestampdiff) <br/>[UNIX_TIMESTAMP()](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_unix-timestamp) |
| [字符串函数](/functions-and-operators/string-functions.md) | [ASCII()](/functions-and-operators/string-functions.md#ascii) <br/>[BIT_LENGTH()](/functions-and-operators/string-functions.md#bit_length) <br/>[CHAR()](/functions-and-operators/string-functions.md#char) <br/>[CHAR_LENGTH()](/functions-and-operators/string-functions.md#char_length) <br/>[CONCAT()](/functions-and-operators/string-functions.md#concat) <br/>[CONCAT_WS()](/functions-and-operators/string-functions.md#concat_ws) <br/>[ELT()](/functions-and-operators/string-functions.md#elt) <br/>[FIELD()](/functions-and-operators/string-functions.md#field) <br/>[HEX()](/functions-and-operators/string-functions.md#hex) <br/>[LENGTH()](/functions-and-operators/string-functions.md#length) <br/>[LIKE](/functions-and-operators/string-functions.md#like) <br/>[LOWER()](/functions-and-operators/string-functions.md#lower) <br/>[LTRIM()](/functions-and-operators/string-functions.md#ltrim) <br/>[MID()](/functions-and-operators/string-functions.md#mid) <br/>[NOT LIKE](/functions-and-operators/string-functions.md#not-like) <br/>[NOT REGEXP](/functions-and-operators/string-functions.md#not-regexp) <br/>[REGEXP](/functions-and-operators/string-functions.md#regexp) <br/>[REGEXP_LIKE()](/functions-and-operators/string-functions.md#regexp_like) <br/>[REGEXP_REPLACE()](/functions-and-operators/string-functions.md#regexp_replace) <br/>[REGEXP_SUBSTR()](/functions-and-operators/string-functions.md#regexp_substr) <br/>[REPLACE()](/functions-and-operators/string-functions.md#replace) <br/>[REVERSE()](/functions-and-operators/string-functions.md#reverse) <br/>[RIGHT()](/functions-and-operators/string-functions.md#right), [RLIKE](/functions-and-operators/string-functions.md#rlike) <br/>[RTRIM()](/functions-and-operators/string-functions.md#rtrim) <br/>[SPACE()](/functions-and-operators/string-functions.md#space) <br/>[STRCMP()](/functions-and-operators/string-functions.md#strcmp) <br/>[SUBSTR()](/functions-and-operators/string-functions.md#substr) <br/>[SUBSTRING()](/functions-and-operators/string-functions.md#substring) <br/>[UPPER()](/functions-and-operators/string-functions.md#upper) |
| [聚合函数](/functions-and-operators/aggregate-group-by-functions.md#group-by-聚合函数) | [COUNT()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_count) <br/>[COUNT(DISTINCT)](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_count-distinct) <br/>[SUM()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_sum) <br/>[AVG()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_avg) <br/>[MAX()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_max) <br/>[MIN()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_min) <br/>[VARIANCE()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_variance) <br/>[VAR_POP()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_var-pop) <br/>[STD()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_std) <br/>[STDDEV()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_stddev) <br/>[STDDEV_POP](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_stddev-pop) <br/>[VAR_SAMP()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_var-samp) <br/>[STDDEV_SAMP()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_stddev-samp) <br/>[JSON_ARRAYAGG(key)](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_json-arrayagg) <br/>[JSON_OBJECTAGG(key, value)](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_json-objectagg) |
| [聚合函数](/functions-and-operators/aggregate-group-by-functions.md#group-by-聚合函数) | [COUNT()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_count) <br/>[COUNT(DISTINCT)](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_count-distinct) <br/>[SUM()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_sum) <br/>[`SUM_INT()`](/functions-and-operators/aggregate-group-by-functions.md) <br/>[AVG()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_avg) <br/>[MAX()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_max) <br/>[MIN()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_min) <br/>[VARIANCE()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_variance) <br/>[VAR_POP()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_var-pop) <br/>[STD()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_std) <br/>[STDDEV()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_stddev) <br/>[STDDEV_POP](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_stddev-pop) <br/>[VAR_SAMP()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_var-samp) <br/>[STDDEV_SAMP()](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_stddev-samp) <br/>[JSON_ARRAYAGG(key)](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_json-arrayagg) <br/>[JSON_OBJECTAGG(key, value)](https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_json-objectagg) |
| [加密和压缩函数](/functions-and-operators/encryption-and-compression-functions.md#加密和压缩函数) | [MD5()](/functions-and-operators/encryption-and-compression-functions.md#md5) <br/>[SHA1(), SHA()](/functions-and-operators/encryption-and-compression-functions.md#sha1) <br/>[UNCOMPRESSED_LENGTH()](/functions-and-operators/encryption-and-compression-functions.md#uncompressed_length) |
| [Cast 函数](/functions-and-operators/cast-functions-and-operators.md#cast-函数和操作符) | [CAST()](/functions-and-operators/cast-functions-and-operators.md#cast) <br/>[CONVERT()](/functions-and-operators/cast-functions-and-operators.md#convert) |
| [其他函数](/functions-and-operators/miscellaneous-functions.md#支持的函数) | [UUID()](/functions-and-operators/miscellaneous-functions.md#uuid) |
Expand Down
4 changes: 2 additions & 2 deletions functions-and-operators/window-functions.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 窗口函数
aliases: ['/docs-cn/dev/functions-and-operators/window-functions/','/docs-cn/dev/reference/sql/functions-and-operators/window-functions/']
summary: TiDB 中的窗口函数与 MySQL 8.0 基本一致。可以将 `tidb_enable_window_function` 设置为 `0` 来解决升级后无法解析语法的问题。TiDB 支持除 `GROUP_CONCAT()` 和 `APPROX_PERCENTILE()` 以外的所有 `GROUP BY` 聚合函数。其他支持的窗口函数包括 `CUME_DIST()`、`DENSE_RANK()`、`FIRST_VALUE()`、`LAG()`、`LAST_VALUE()`、`LEAD()`、`NTH_VALUE()`、`NTILE()`、`PERCENT_RANK()`、`RANK()` 和 `ROW_NUMBER()`。这些函数可以下推到 TiFlash。
summary: TiDB 中的窗口函数与 MySQL 8.0 基本一致。可以将 `tidb_enable_window_function` 设置为 `0` 来解决升级后无法解析语法的问题。TiDB 支持除 `GROUP_CONCAT()`、`APPROX_PERCENTILE()` 和 `APPROX_COUNT_DISTINCT()` 以外的所有 `GROUP BY` 聚合函数作为窗口函数,包括 `SUM_INT()`、`MAX_COUNT()` 和 `MIN_COUNT()`。其他支持的窗口函数包括 `CUME_DIST()`、`DENSE_RANK()`、`FIRST_VALUE()`、`LAG()`、`LAST_VALUE()`、`LEAD()`、`NTH_VALUE()`、`NTILE()`、`PERCENT_RANK()`、`RANK()` 和 `ROW_NUMBER()`。这些函数可以下推到 TiFlash。
---

# 窗口函数
Expand All @@ -16,7 +16,7 @@ TiDB 中窗口函数的使用方法与 MySQL 8.0 基本一致,详情可参见

[本页](/tiflash/tiflash-supported-pushdown-calculations.md)列出的窗口函数可以下推到 TiFlash。

TiDB 支持除 `GROUP_CONCAT()` 和 `APPROX_PERCENTILE()` 以外的所有 [`GROUP BY` 聚合函数](/functions-and-operators/aggregate-group-by-functions.md)作为窗口函数。此外,TiDB 支持的其他窗口函数如下:
TiDB 支持除 `GROUP_CONCAT()`、`APPROX_PERCENTILE()` 和 `APPROX_COUNT_DISTINCT()` 以外的所有 [`GROUP BY` 聚合函数](/functions-and-operators/aggregate-group-by-functions.md)作为窗口函数,包括 `SUM_INT()`、`MAX_COUNT()` 和 `MIN_COUNT()`。此外,TiDB 支持的其他窗口函数如下:

| 函数名 | 功能描述 |
| :-------------- | :------------------------------------- |
Expand Down
Loading
Loading