2016-06-20 4 views
3

Предположим, что у нас есть что-то данные, как это:GROUP_CONCAT в Vertica

date | campaign | raw | unq 
------------+----------+-----+----- 
2016-06-01 | camp1 | 5 | 1 
2016-06-01 | camp2 | 10 | 1 
2016-06-01 | camp3 | 15 | 2 
2016-06-02 | camp4 | 5 | 3 
2016-06-02 | camp1 | 5 | 1 

Мне нужно сгруппировать его таким образом, чтобы получить следующий результат:

date | campaigns   | raw | unq 
------------+---------------------+----- +----- 
2016-06-01 | camp1, camp2, camp3 | 30 | 4 
2016-06-02 | camp4, camp1  | 10 | 4 

Mysql для этих целей имеет функция GROUP_CONCAT. Vertica также поддерживает GROUP_CONCAT, но я не могу сделать надлежащий запрос в связи с пунктом OVER и обязательного разделения

+0

Зачем вам нужно предложение OVER, если вы только группируете по дате? –

+0

Поскольку GROUP_CONCAT требует предложения OVER в любом случае –

ответ

3

Предполагая, что вы собрали и создали функцию в каталоге sdk/examples, вы должны быть в состоянии сделать:

select date, sum(raw) "raw", sum(unq) unq, rtrim(agg_concatenate(campaign || ', '),', ') 
from mytest 
group by 1 
order by 1 

Я использую rtrim, чтобы избавиться от последнего ','.

Если вы не создали его, вы можете сделать так:

-- Shell commands 
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 

-- vsql commands 
CREATE LIBRARY AggregateFunctionsConcatenate AS '/opt/vertica/sdk/examples/AggregateFunctions/Concatenate.so'; 
CREATE AGGREGATE FUNCTION agg_concatenate AS LANGUAGE 'C++' NAME 'ConcatenateFactory' LIBRARY AggregateFunctionsConcatenate; 
1

Единственный способ, который я знаю, чтобы использовать group_concat этот путь будет делать только запрашивать данные по отдельности и объединить их в конце , Это некрасиво, и я предпочитаю другой метод, который я опубликовал, но это более прямой ответ на ваш вопрос.

with camps as (
    select date, group_concat(campaign) over (partition by date) campaigns 
    from mytest 
), sums as (
    select date, sum(raw) "raw", sum(unq) unq 
    from mytest 
    group by date 
) 
select c.date, "raw", unq, campaigns 
from camps c 
join sums s on (c.date = s.date) 
Смежные вопросы