Vertica 数据库实现LISTAGG 聚合函数

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

/* Copyright (c) 2005 - 2015 Hewlett Packard Enterprise Development LP -*- C++ -*- */
/* 
 * Description: Example User Defined Aggregate Function: ListAgg strings
 *
 */

#include "Vertica.h"
#include <time.h> 
#include <sstream>
#include <iostream>

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<ListAgg>(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

输入图片说明

转载于:https://my.oschina.net/yjwu/blog/1627244

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vertica数据库是一种高性能、可扩展的关系型数据库管理系统。它可以处理大规模数据,并提供快速的查询和分析能力。在安装和配置Vertica数据库时,有一些步骤需要注意。 首先,需要切换到数据库管理员用户下,而不是使用root用户。可以使用以下命令切换到vdbadmin用户: \[su vdbadmin\] \[1\] 接下来,可以使用Vertica提供的admintools工具来管理数据库。可以使用以下命令来启动admintools: \[/opt/vertica/bin/admintools\] \[1\] 在安装Vertica数据库之前,还需要禁用透明大页功能。可以使用以下命令来禁用透明大页: \[echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled\] \[2\] 然后,可以使用install_vertica命令来创建节点并指定数据库管理员。可以使用以下命令来执行安装: \[/opt/vertica/sbin/install_vertica --host 192.168.116.128 --rpm /root/vertica-9.2.1-7.x86_64.RHEL6.rpm --failure-threshold FAIL --dba-user vdbadmin\] \[3\] 通过以上步骤,您可以成功安装和配置Vertica数据库。请确保按照指定的命令和参数进行操作,以确保正确安装和配置数据库。 #### 引用[.reference_title] - *1* *2* *3* [Linux(Centos6.5)下安装Vertica9.2.1数据库教程](https://blog.csdn.net/hu1010037197/article/details/102705393)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值