listagg用mysql实现_Vertica 数据库实现LISTAGG 聚合函数

本文介绍了如何在Vertica数据库中实现类似MySQL的LISTAGG聚合函数,通过自定义的User Defined Aggregate Function (UDAF) `ListAgg`,将字符串连接在一起。该函数考虑了输入字符串的最大长度,并提供了处理分隔符的选项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过改造例子中的 Concatenate 实现。

/* Copyright (c) 2005 - 2015 Hewlett Packard Enterprise Development LP -*- C++ -*- */

/*

* Description: Example User Defined Aggregate Function: ListAgg strings

*

*/

#include "Vertica.h"

#include

#include

#include

using namespace Vertica;

using namespace std;

/**

* User Defined Aggregate Function ListAgg that takes in strings and concatenates

* them together. Right now, the max length of the resulting string is ten times the

* maximum length of the input string.

*/

class ListAgg : public AggregateFunction

{

virtual void initAggregate(ServerInterface &srvInterface, IntermediateAggs &aggs)

{

//初始化聚合函数返回结果

try {

VString &concat = aggs.getStringRef(0);

concat.copy("");

} catch(exception& e) {

// Standard exception. Quit.

vt_report_error(0, "Exception while initializing intermediate aggregates: [%s]", e.what());

}

}

void aggregate(ServerInterface &srvInterface,

BlockReader &argReader,

IntermediateAggs &aggs)

{

//获取分割字符串

// Get the value of splitstr from the parameters

ParamReader paramReader = srvInterface.getParamReader();

if (!paramReader.containsParameter("splitstr")) {

vt_report_error(0, "You must provide a value for parameter splitstr");

}

VString splitstr = paramReader.getStringRef("splitstr");

try {

VString &concat = aggs.getStringRef(0);

string word = concat.str();

uint32 maxSize = aggs.getTypeMetaData().getColumnType(0).getStringLength();

do {

const VString &input = argReader.getStringRef(0);

if (!input.isNull()) {

if ((word.length() + input.length()+splitstr.length()) > maxSize) break;//不能超过最大长度

word.append(input.str());

word.append(splitstr.str());

}

} while (argReader.next());

concat.copy(word);

} catch(exception& e) {

// Standard exception. Quit.

vt_report_error(0, "Exception while processing aggregate: [%s]", e.what());

}

}

virtual void combine(ServerInterface &srvInterface,

IntermediateAggs &aggs,

MultipleIntermediateAggs &aggsOther)

{

// Get the value of splitstr from the parameters

ParamReader paramReader = srvInterface.getParamReader();

if (!paramReader.containsParameter("splitstr")) {

vt_report_error(0, "You must provide a value for parameter splitstr");

}

VString splitstr = paramReader.getStringRef("splitstr");

try {

uint32 maxSize = aggs.getTypeMetaData().getColumnType(0).getStringLength();

VString myConcat = aggs.getStringRef(0);

do {

const VString otherConcat = aggsOther.getStringRef(0);

if ((myConcat.length() + otherConcat.length()+splitstr.length()) <= maxSize) {

string word = myConcat.str();

word.append(otherConcat.str());

//word.append(splitstr.str());

myConcat.copy(word);

}

} while (aggsOther.next());

} catch(exception& e) {

// Standard exception. Quit.

vt_report_error(0, "Exception while combining intermediate aggregates: [%s]", e.what());

}

}

virtual void terminate(ServerInterface &srvInterface,

BlockWriter &resWriter,

IntermediateAggs &aggs)

{

// Get the value of splitstr from the parameters

ParamReader paramReader = srvInterface.getParamReader();

if (!paramReader.containsParameter("splitstr")) {

vt_report_error(0, "You must provide a value for parameter splitstr");

}

VString splitstr = paramReader.getStringRef("splitstr");

try {

const VString &concat = aggs.getStringRef(0);

VString &result = resWriter.getStringRef();

result.copy(concat.str().substr(0,concat.length()-splitstr.length())); //截断最后的splitstr

} catch(exception& e) {

// Standard exception. Quit.

vt_report_error(0, "Exception while computing aggregate output: [%s]", e.what());

}

}

InlineAggregate()

};

class ListAggFactory : public AggregateFunctionFactory

{

virtual void getIntermediateTypes(ServerInterface &srvInterface, const SizedColumnTypes &inputTypes, SizedColumnTypes &intermediateTypeMetaData)

{

int input_len = inputTypes.getColumnType(0).getStringLength();

intermediateTypeMetaData.addVarchar(input_len*10);

}

virtual void getPrototype(ServerInterface &srvfloaterface, ColumnTypes &argTypes, ColumnTypes &returnType)

{

argTypes.addVarchar();//输入函数字符串类型(聚合函数只能一个参数 ,只能使用 using parameters 增加额外参数)

returnType.addVarchar();

}

virtual void getReturnType(ServerInterface &srvfloaterface,

const SizedColumnTypes &inputTypes,

SizedColumnTypes &outputTypes)

{

int input_len = inputTypes.getColumnType(0).getStringLength();

outputTypes.addVarchar(input_len*10);

}

virtual void getParameterType(ServerInterface &srvInterface,

SizedColumnTypes &parameterTypes)

{

parameterTypes.addVarchar(10,"splitstr");//额外参数,使用 using parameters 增加额外参数

}

virtual AggregateFunction *createAggregateFunction(ServerInterface &srvfloaterface)

{ return vt_createFuncObject(srvfloaterface.allocator); }

};

RegisterFactory(ListAggFactory);

测试例子

select DEALER_CD ,public.LISTAGG(TPTYPE using parameters splitstr=',') as TPTYPE from (

SELECT distinct

DEALER_CD,

trim( TPTYPE) TPTYPE

FROM

DW.F_CR_EXIST_CUSTOMER

where trim( TPTYPE)!=''

)t group by DEALER_CD

e86c7efaec096defd6bb8ab76794da1b.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值