2016-08-29 2 views
5

Я хотел бы объединить два столбца, используя запрос группы, в результате чего получается массив, разделенный скобками. Я знаю, что этот вопрос связан с вопросом this, но, как обычно, мой прецедент немного отличается.Как агрегировать два столбца PostgreSQL в массив, разделенный скобками

Простой пример (также как SQL Fiddle). В настоящее время мой запрос возвращает следующее:

ID X Y 
3 0.5 2.71 
3 1.0 2.50 
3 1.5 2.33 
6 0.5 2.73 
6 1.5 2.77 

Но где я хотел бы сцепить/для агрегации X/Y столбцов, чтобы получить следующее:

ID XY 
3 [[0.5,2.71],[1.0,2.50],[1.5,2.33]] 
6 [[0.5,2.73],[1.5,2.77]] 

В настоящее время я пытался объединить столбцы в один следующим образом:

SELECT "ID",concat_ws(', ',"X", "Y") as XY FROM Table1; 

Который возвращает:

ID xy 
3 0.5, 2.71 
3 1, 2.50 
3 1.5, 2.33 
6 0.5, 2.73 

И использовали array_agg():

SELECT "ID",array_to_string(array_agg("X"),',') AS XY 
FROM Table1 
GROUP BY "ID"; 

Результирующее в:

ID xy 
3 0.5,1,1.5 
6 0.5 

Я чувствую, что я все ближе, но руку помощи будет очень ценна.

ответ

8

Создать массив из двух столбцов, совокупность массива:

select id, array_agg(array[x,y]) 
from the_table 
group by id; 

Обратите внимание, что текстовое представление по умолчанию массивов используются фигурные скобки ({..}) не квадратные скобки ([..])

+0

Спасибо за ваш быстрый ответ, он отлично работает в postgresql (не в sqlfiddle) – Mattijn

+0

@Mattijn: Ваша версия, очевидно, 9.5 или более поздней. sqlfiddle застрял в 9.3 в течение некоторого времени. –

+2

Кроме того, тип x и y должен быть таким же, т.е. если x имеет текст, тогда y также должен иметь текст типа. Если нет, вам нужно использовать случай типа. (:: текст) –

3

В Postgres 9.5 или более поздней версииarray_agg() принимает массивы в качестве входных данных, чтобы позволить простой синтаксис provided by @a_horse:

SELECT id, array_agg(ARRAY[x, y]) AS xy 
FROM Table1 
GROUP BY id; 

В более старые версии, это еще не реализовано. Вы можете создать свою собственную функцию агрегата (один раз), чтобы достигнуть того же самого:

CREATE AGGREGATE array_agg_mult (anyarray) (
    SFUNC  = array_cat 
    , STYPE  = anyarray 
    , INITCOND = '{}' 
); 

Тогда:

SELECT id, array_agg_mult(ARRAY[ARRAY[x,y]]) AS xy -- note the 2D array 
FROM Table1 
GROUP BY id; 

Детали:

Или вы можете сцепить строка:

SELECT id, '[[' || string_agg(concat_ws(',', x, y), '],[') || ']]' AS xy 
FROM Table1 
GROUP BY id; 

Производит нужный результат точно. Строка, а не массив.

+0

Спасибо, ваш ответ также полезен – Mattijn

Смежные вопросы