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

Wybierz komórki wierszy jako nowe kolumny

To pytanie było o wiele trudniejsze rozwiązać, niż mogłeś się spodziewać. Twoja próba z crosstab() zmierzał we właściwym kierunku. Ale aby przypisać dynamiczne nazwy kolumn, potrzebujesz dodatkowo dynamicznego SQL:EXECUTE w funkcji plpgsql.

Zmień typ danych kolumny infos.type z text do regtype aby zapobiec wstrzyknięciu SQL i innym błędom. Na przykład masz typ danych number , który nie jest prawidłowym typem danych PostgreSQL. Zamieniłem go na numeric , więc może działać.

możesz uprość zadanie, unikając nazw kolumn, które wymagają podwójnego cudzysłowu. Jak nume_anterior zamiast "nume anterior" .

Możesz dodać kolumnę row_id do Twojej tabeli info_data aby zaznaczyć wszystkie elementy jednego rzędu. Potrzebujesz go do crosstab() funkcja i pozwala ignorować kolumny z NULL wartości. crosstab() funkcja z dwoma parametrami może poradzić sobie z brakującymi kolumnami. Brakującą kolumnę syntetyzuję za pomocą wyrażenia (d.id-1)/13 poniżej - co działa dla danych w twoim przykładzie.

Musisz zainstalować dodatkowy moduł tablefunc (raz na bazę danych):

CREATE EXTENSION tablefunc;

Znajdź dodatkowe wyjaśnienia i linki w tej powiązanej odpowiedzi .

Ta funkcja zrobi to, czego szukasz:

CREATE OR REPLACE FUNCTION f_mytbl()
  RETURNS TABLE (id int
, nume text           , prenume text       , cnp numeric
, "nume anterior" text, "stare civila" text, cetatenie text
, rezidenta text      , adresa text        , "tip act" text
, "serie ci" text     , "numar ci" text    , "data eliberarii" text
, "eliberat de" text)
  LANGUAGE plpgsql AS
$BODY$
BEGIN

RETURN QUERY EXECUTE $f$
SELECT *
FROM   crosstab(
    'SELECT (d.id-1)/13 -- AS row_id
          , i.id, d.value
     FROM   infos i
     JOIN   info_data d ON d.id_info = i.id
     ORDER  BY 1, i.id',

    'SELECT id
     FROM   infos
     ORDER  BY id'
    )
AS tbl ($f$ || 'id int,
, nume text           , prenume text       , cnp numeric
, "nume anterior" text, "stare civila" text, cetatenie text
, rezidenta text      , adresa text        , "tip act" text
, "serie ci" text     , "numar ci" text    , "data eliberarii" text
, "eliberat de" text)';

END;
$BODY$;

Zadzwoń:

SELECT * FROM x.mytbl();

Nie daj się zmylić zagnieżdżonym cytowanie dolara .

BTW:Stworzyłem listę kolumn za pomocą tego stwierdzenia:

SELECT 'id int,' || string_agg(quote_ident(name) || ' ' || type
                              ,', ' ORDER BY i.id) 
FROM   infos i;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Używanie wielu schematów PostgreSQL z modelami Rails

  2. Zaktualizuj istniejący wiersz w bazie danych z pandy df

  3. PostgreSQL 9.2 - Konwertuj TEKSTOWY ciąg json na typ json/hstore

  4. Sprawdź, czy baza danych istnieje w PostgreSQL za pomocą powłoki

  5. Docker i Postgres:nie udało się powiązać adresu tcp 0.0.0.0:5432, który jest już używany