Concat GROUP BY in Vertica SQL

前端 未结 3 529
北海茫月
北海茫月 2020-12-11 07:24

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 | na         


        
相关标签:
3条回答
  • 2020-12-11 07:34

    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
    0 讨论(0)
  • 2020-12-11 07:44

    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.

    0 讨论(0)
  • 2020-12-11 07:51

    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.

    0 讨论(0)
提交回复
热议问题