PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Изберете клетки от ред като нови колони

Този въпрос беше много по-труден за решаване, отколкото може би сте очаквали. Вашият опит с crosstab() се е насочил в правилната посока. Но за да зададете имена на динамични колони, имате нужда от динамичен SQL в допълнение:EXECUTE във функция plpgsql.

Променете типа данни на колоната infos.type от text до regtype за предотвратяване на SQL инжектиране и други грешки. Например, имате тип данни number , което не е валиден тип данни на PostgreSQL. Замених го с numeric , за да може да работи.

Вие можете опростете задачата, като избягвате имена на колони, които се нуждаят от двойни кавички. Като nume_anterior вместо "nume anterior" .

Може да искате да добавите колона row_id към вашата таблица info_data за маркиране на всички елементи от един ред. Имате нужда от него за crosstab() функция и ви позволява да игнорирате колони с NULL стойности. crosstab() функция с два параметъра може да се справи с липсващи колони. Синтезирам липсващата колона с израза (d.id-1)/13 по-долу - което работи за данните във вашия пример.

Трябва да инсталирате допълнителния модул tablefunc (веднъж за база данни):

CREATE EXTENSION tablefunc;

Намерете допълнително обяснение и връзки в този свързан отговор .

Тази функция ще направи това, което търсите:

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$;

Обаждане:

SELECT * FROM x.mytbl();

Не се обърквайте от вложеното котиране на долара .

BTW:Създадох списъка с колони с този израз:

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. Работата на pgAgent е неуспешна с грешка при удостоверяване

  2. Как да добавя колона, ако не съществува в PostgreSQL?

  3. Приоритет, базиран на времето в заявка за активен запис

  4. psql ГРЕШКА:не може да се отвори файл адрес.csv за четене:Няма такъв файл или директория

  5. Режимът H2 postgresql изглежда не работи за мен