Как связать строки строкового поля в PostgreSQL 'группа' запросом?

Как выделить смежный многомерный массив в GNU C ++? Существует расширение GNU, которое позволяет использовать «стандартный» синтаксис.

Кажется, проблема исходит от оператора new []. Убедитесь, что вместо этого вы используете новый оператор:

double (* in)[n][n] = new (double[m][n][n]);  // GNU extension

И это все: вы получаете C-совместимый многомерный массив ...

329
задан a_horse_with_no_name 14 December 2017 в 21:03
поделиться

8 ответов

PostgreSQL 9.0 или позже:

Последние версии Пост-ГРЭС (с конца 2010 года) имеют string_agg(expression, delimiter) функция, которая сделает точно что вопрос, для которого задают, даже позволяя Вам определить строку разделителя:

SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;

Пост-ГРЭС 9.0 также добавила способность определить ORDER BY пункт в любом составном выражении ; иначе порядок не определен. Таким образом, можно теперь записать:

SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;

Или действительно:

SELECT string_agg(actor_name, ', ' ORDER BY first_appearance)

PostgreSQL 8.4 или позже:

PostgreSQL 8.4 (в 2009) представил агрегатная функция array_agg(expression) , которая связывает значения в массив. Тогда array_to_string() может использоваться для предоставления желаемого результата:

SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;

string_agg для пред9.0 версий:

В случае, если любой сталкивается с этим поиском контейнера совместимости для пред9.0 баз данных, возможно реализовать все в [1 117] кроме ORDER BY пункт.

Так с ниже определения это должно работать то же в 9.x DB Пост-ГРЭС:

SELECT string_agg(name, '; ') AS semi_colon_separated_names FROM things;

, Но это будет синтаксической ошибкой:

SELECT string_agg(name, '; ' ORDER BY name) AS semi_colon_separated_names FROM things;
--> ERROR: syntax error at or near "ORDER"

Протестированный на PostgreSQL 8.3.

CREATE FUNCTION string_agg_transfn(text, text, text)
    RETURNS text AS 
    $
        BEGIN
            IF $1 IS NULL THEN
                RETURN $2;
            ELSE
                RETURN $1 || $3 || $2;
            END IF;
        END;
    $
    LANGUAGE plpgsql IMMUTABLE
COST 1;

CREATE AGGREGATE string_agg(text, text) (
    SFUNC=string_agg_transfn,
    STYPE=text
);

Пользовательские изменения (все версии Пост-ГРЭС)

До 9,0, не было никакой встроенной агрегатной функции для конкатенации строк. Самая простая пользовательская реализация ( предложенный Vajda Gabo в этом сообщении списка рассылки , среди многих других) должна использовать встроенное textcat функция (который стоит за || оператор):

CREATE AGGREGATE textcat_all(
  basetype    = text,
  sfunc       = textcat,
  stype       = text,
  initcond    = ''
);

Вот CREATE AGGREGATE документация.

Это просто склеивает все строки без разделителя. Для получения", "вставленный промежуточный их, не имея его в конце, Вы могли бы хотеть сделать свою собственную функцию конкатенации и заменить им "textcat" выше. Вот тот, который я соединил и протестировал на 8.3.12:

CREATE FUNCTION commacat(acc text, instr text) RETURNS text AS $
  BEGIN
    IF acc IS NULL OR acc = '' THEN
      RETURN instr;
    ELSE
      RETURN acc || ', ' || instr;
    END IF;
  END;
$ LANGUAGE plpgsql;

Эта версия произведет запятую, даже если значение в строке будет пустым или пустым, таким образом, Вы производитесь как это:

a, b, c, , e, , g

, Если Вы предпочли бы удалять дополнительные запятые для вывода этого:

a, b, c, e, g

Тогда добавляют ELSIF проверка к функции как это:

CREATE FUNCTION commacat_ignore_nulls(acc text, instr text) RETURNS text AS $
  BEGIN
    IF acc IS NULL OR acc = '' THEN
      RETURN instr;
    ELSIF instr IS NULL OR instr = '' THEN
      RETURN acc;
    ELSE
      RETURN acc || ', ' || instr;
    END IF;
  END;
$ LANGUAGE plpgsql;
512
ответ дан Neall 23 November 2019 в 00:46
поделиться

Я нашел эту документацию PostgreSQL полезной: http://www.postgresql.org/docs/8.0/interactive/functions-conditional.html .

В моем случае, я искал плоскость SQL для конкатенации поля со скобками вокруг этого, если поле не пусто.

select itemid, 
  CASE 
    itemdescription WHEN '' THEN itemname 
    ELSE itemname || ' (' || itemdescription || ')' 
  END 
from items;
3
ответ дан 23 November 2019 в 00:46
поделиться

Этот последний отрывок списка объявления мог бы представлять интерес, если Вы будете обновлять до 8,4:

До 8.4 выпускает super-effient собственный, можно добавить array_accum () функция в документации PostgreSQL для свертывания любого столбца в массив, который может затем использоваться кодом приложения или объединяться с array_to_string () для форматирования его как списка:

http://www.postgresql.org/docs/current/static/xaggr.html

я связался бы с 8,4 документами разработки, но они, кажется еще, не перечисляют эту функцию.

5
ответ дан Kev 23 November 2019 в 00:46
поделиться

Как уже упомянуто, создавание Вашей собственной агрегатной функции является правильным поступком. Вот моя агрегатная функция конкатенации (можно найти детали на французском языке ):

CREATE OR REPLACE FUNCTION concat2(text, text) RETURNS text AS '
    SELECT CASE WHEN $1 IS NULL OR $1 = \'\' THEN $2
            WHEN $2 IS NULL OR $2 = \'\' THEN $1
            ELSE $1 || \' / \' || $2
            END; 
'
 LANGUAGE SQL;

CREATE AGGREGATE concatenate (
  sfunc = concat2,
  basetype = text,
  stype = text,
  initcond = ''

);

И затем используют его как:

SELECT company_id, concatenate(employee) AS employees FROM ...
7
ответ дан bortzmeyer 23 November 2019 в 00:46
поделиться

Я не требую никакого кредита на ответ, потому что я нашел его после некоторого поиска:

то, Что я не знал, - то, что PostgreSQL позволяет, Вы для определения собственных агрегатных функций с СОЗДАЕТЕ АГРЕГАТ

Это сообщение на шоу списка PostgreSQL, как тривиальный это должно создать функцию, чтобы сделать то, что требуется:

CREATE AGGREGATE textcat_all(
  basetype    = text,
  sfunc       = textcat,
  stype       = text,
  initcond    = ''
);

SELECT company_id, textcat_all(employee || ', ')
FROM mytable
GROUP BY company_id;
13
ответ дан Guy C 23 November 2019 в 00:46
поделиться

Продолжение ответа Кева с использованием документов Postgres:

Сначала , создайте массив элементов, затем используйте встроенную функцию array_to_string .

CREATE AGGREGATE array_accum (anyelement)
(
 sfunc = array_append,
 stype = anyarray,
 initcond = '{}'
);

select array_to_string(array_accum(name),'|') from table group by id;
5
ответ дан 23 November 2019 в 00:46
поделиться

Еще раз повторяя использование настраиваемой агрегатной функции конкатенации строк: вам нужно помнить, что оператор select будет размещать строки в любом порядке, поэтому вам нужно будет выполнить sub выберите в операторе из с предложением order by , а затем внешний select с группой group by , чтобы объедините строки, таким образом:

SELECT custom_aggregate(MY.special_strings)
FROM (SELECT special_strings, grouping_column 
        FROM a_table 
        ORDER BY ordering_column) MY
GROUP BY MY.grouping_column
5
ответ дан 23 November 2019 в 00:46
поделиться

Как насчет использования встроенных функций массива Postgres? По крайней мере, в 8.4 это работает "из коробки":

SELECT company_id, array_to_string(array_agg(employee), ',')
FROM mytable
GROUP BY company_id;
92
ответ дан 23 November 2019 в 00:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: