PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak połączyć ciągi w polu ciągu w zapytaniu PostgreSQL „grupuj według”?

PostgreSQL 9.0 lub nowszy:

Nowoczesny Postgres (od 2010) ma string_agg(expression, delimiter) funkcja, która zrobi dokładnie to, czego szukał pytający:

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

Postgres 9 dodał również możliwość określenia ORDER BY klauzula w dowolnym wyrażeniu zagregowanym; w przeciwnym razie musisz uporządkować wszystkie wyniki lub zająć się niezdefiniowaną kolejnością. Możesz więc teraz pisać:

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

PostgreSQL 8.4.x:

PostgreSQL 8.4 (w 2009) wprowadził funkcję agregującą array_agg(expression) który zbiera wartości w tablicy. Następnie array_to_string() może być użyty do uzyskania pożądanego rezultatu:

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

PostgreSQL 8.3.x i starsze:

Kiedy to pytanie było pierwotnie postawione, nie było wbudowanej funkcji agregującej do łączenia ciągów. Najprostszą niestandardową implementacją (sugerowaną przez Vajdę Gabo w tym poście na liście dyskusyjnej, między innymi, między innymi) jest użycie wbudowanego textcat funkcja (która leży za || operator):

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

Oto CREATE AGGREGATE dokumentacja.

To po prostu skleja wszystkie struny ze sobą, bez separatora. Aby wstawić „,” między nimi bez umieszczania go na końcu, możesz utworzyć własną funkcję konkatenacji i zastąpić ją „textcat” powyżej. Oto jeden, który złożyłem i przetestowałem w 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;

Ta wersja wypisze przecinek, nawet jeśli wartość w wierszu jest pusta lub pusta, więc otrzymujesz dane wyjściowe w następujący sposób:

a, b, c, , e, , g

Jeśli wolisz usunąć dodatkowe przecinki, aby to wypisać:

a, b, c, e, g

Następnie dodaj ELSIF sprawdź funkcję w następujący sposób:

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;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Heroku Postgres Error:PGError:ERROR:organizacje relacyjne nie istnieją (ActiveRecord::StatementInvalid)

  2. Zatwierdzanie transakcji podczas wykonywania funkcji postgreql

  3. Jak stworzyć użytkownika w PostgreSQL

  4. Jak przekonwertować datę i godzinę na wartość epoki uniksowej w Postgresie?

  5. Moje ulubione rozszerzenia PostgreSQL — część pierwsza