# **GROUP\_CONCAT**

将字段的值连接为指定分隔符分隔的字符串。

## 语法{#grammar}

GROUP\_CONCAT(**field**, **\[partitionfield]**, **\[orderfield]**, **\[ordertype]**, **\[separator]**, **\[maxlength]**)

- **field**：必需，要连接的字段
- **partitionfield**：可选，分组字段，使用partitionby括起，只在oracle有效
- **orderfield**：可选，排序字段，field字段值按什么顺序连接，使用orderby括起，只在mysql和oracle有效
- **ordertype**：可选，指定排序类型，'asc'升序，'desc'降序，默认为升序
- **separator**：可选，分隔符，默认为逗号
- **maxlength**：可选，连接字符串的最大长度，只在vertica和oracle有效

## 示例{#example}

1. `GROUP_CONCAT([电影演员表].[电影名称],"、")` 用顿号连接演员参演电影名称
2. `GROUP_CONCAT([电影演员表].[电影名称],ORDERBY([电影演员表].[排序序号],'desc'),"、")` 用顿号连接演员参演电影名称，以排序序号降序排列

不同的数据库用法不同，下面分数据库举例。

### Oracle

使用listagg实现，支持Oracle11及以上版本，是一个聚合函数，也是窗口函数，支持partitionby子句。

- maxlength 由于oracle的字符串varchar大小限制为4000，因此使用listagg拼接字符串时可能会出现字符串长度超过限制的异常，使用xmlagg+xmlparse来代替，
  当指定maxlength大于4000，使用xmlagg+xmlparse来实现。注意：***代替的方法不支持partitionby子句***。

1. `GROUP_CONCAT([主体登记表].[经营范围], ';')`  按groupby语句分组，用分号连接经营范围。
2. `GROUP_CONCAT([主体登记表].[经营范围], orderby([主体登记表].[注册资金], 'desc'), ';')` 按groupby语句分组，注册资金降序，用分号连接经营范围。
3. `GROUP_CONCAT([主体登记表].[经营范围], partitionby([主体登记表].[法人]), orderby([主体登记表].[注册资金], 'desc'))` 按企业法人分组，注册资金降序，用逗号连接经营范围。
4. `GROUP_CONCAT([主体登记表].[经营范围], ';', 4001)`  按groupby语句分组，用分号连接经营范围。使用xmlagg+xmlparse来实现

### MySQL

在MySQL下，此函数是一个聚合函数，只能用于有groupby语句的sql中。

1. `GROUP_CONCAT([主体登记表].[经营范围], ';')`  按groupby语句分组，用分号连接经营范围。
2. `GROUP_CONCAT([主体登记表].[经营范围], orderby([主体登记表].[注册资金], 'desc'), ';')` 按groupby语句分组，注册资金降序，用分号连接经营范围。

### Vertica

使用listagg实现，支持Vertica9及以上版本，只是一个聚合函数，且有如下限制：

- 只能用于有groupby语句的sql中。
- 不支持partitionby子句。
- 不支持排序，即orderby子句。
- maxlength 默认为10240，最大支持65535。

1. `GROUP_CONCAT([主体登记表].[经营范围], ';')`  按groupby语句分组，用分号连接经营范围。
2. `GROUP_CONCAT([主体登记表].[经营范围], ';', 65535)`  按groupby语句分组，用分号连接经营范围。
3. `GROUP_CONCAT([主体登记表].[经营范围], 65535)`  按groupby语句分组，用逗号连接经营范围。
