Concat GROUP BY in Vertica SQL

匿名 (未验证) 提交于 2019-12-03 01:12:01

问题:

I need to get a comma separated list of ids as a field for a messy third party api :s This is a simplified version of what I am trying to achieve.

| id | name | |====|======| | 01 | greg | | 02 | paul | | 03 | greg | | 04 | greg | | 05 | paul |  SELECT name, {some concentration function} AS ids FROM table GROUP BY name 

Returning

| name | ids        | |======|============| | greg | 01, 03, 04 | | paul | 02, 05     | 

I know MySQL has the CONCAT_GROUP function and I was hoping to solve this problem without installing more functions because of the environment. Maybe I can solve this problem using an OVER statement?

回答1:

The easiest on the long term is to use one of the official Vertica UDFs to be found on github at https://github.com/vertica/Vertica-Extension-Packages/tree/master/strings_package which provides a group_concat function. The installation procedure is to found in the README, and examples are even provided.



回答2:

You'll have to use OVER() with NVL() (you'll have to extend the concatenation for more than 10 instances per name):

CREATE TABLE t1 (   id int,   name varchar(10) );  INSERT INTO t1 SELECT 1 AS id, 'greg' AS name UNION ALL SELECT 2, 'paul' UNION ALL SELECT 3, 'greg' UNION ALL SELECT 4, 'greg' UNION ALL SELECT 5, 'paul';  COMMIT;  SELECT name,     MAX(DECODE(row_number, 1, a.id)) ||     NVL(MAX(DECODE(row_number, 2, ',' || a.id)), '') ||     NVL(MAX(DECODE(row_number, 3, ',' || a.id)), '') ||     NVL(MAX(DECODE(row_number, 4, ',' || a.id)), '') ||     NVL(MAX(DECODE(row_number, 5, ',' || a.id)), '') ||     NVL(MAX(DECODE(row_number, 6, ',' || a.id)), '') ||     NVL(MAX(DECODE(row_number, 7, ',' || a.id)), '') ||     NVL(MAX(DECODE(row_number, 8, ',' || a.id)), '') ||     NVL(MAX(DECODE(row_number, 9, ',' || a.id)), '') ||     NVL(MAX(DECODE(row_number, 10, ',' || a.id)), '') id FROM     (SELECT name, id, ROW_NUMBER() OVER(PARTITION BY name ORDER BY id) row_number FROM t1) a GROUP BY a.name ORDER BY a.name; 

Result

 name |  id ------+-------  greg | 1,3,4  paul | 2,5


回答3:

Have look at Concatenate UDAF in vertica examples which comes with vertica installation that's the mysql equivalent. you can just directly install it.

more /opt/vertica/sdk/examples/AggregateFunctions/Concatenate.cpp

-- Shell comppile cd /opt/vertica/sdk/examples/AggregateFunctions/ g++ -D HAVE_LONG_INT_64 -I /opt/vertica/sdk/include -Wall -shared -Wno-unused-value \ -fPIC -o Concatenate.so Concatenate.cpp /opt/vertica/sdk/include/Vertica.cpp  -- Create LIBRARY CREATE LIBRARY AggregateFunctionsConcatenate AS '/opt/vertica/sdk/examples/AggregateFunctions/Concatenate.so'; CREATE AGGREGATE FUNCTION agg_group_concat AS LANGUAGE 'C++' NAME 'ConcatenateFactory' LIBRARY AggregateFunctionsConcatenate;   in the Concatenate.cpp replace : input_len*10 with : 65000 

there is two place you have to replace this value in the code.

65000 is the max length you can get with varchar. and since vertica doesnt uses all of 65000 for the values smaller than 65000 character you are fine.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!