procedimientos linea into funciones espaƱol datos consultas con comandos bases administraciĆ³n sql postgresql row crosstab

linea - Fila de PostgreSQL a columnas



linea de comandos postgresql (1)

Intento crear un sistema dinámico que permita a los usuarios importar listas de datos de Excel, así que necesito tener columnas dinámicas, por ejemplo:

custom_columns_table id list_id data_type column_name data .... 1 1 VARCHAR(255) email [email protected] .... 2 1 VARCHAR(255) name Jhon .... list_table id 1

Necesito un resultado como este:

id email name .... 1 [email protected] Jhon ....

He encontrado algunos ejemplos con tablas cruzadas, pero no sé si funcionarán en este caso.

¿Alguien sabe cómo puedo hacer esto?


En primer lugar, la familia de funciones crosstab() no está instalada en PostgreSQL estándar. Necesita instalar la extensión tablefunc para esto. En PostgreSQL 9.1, simplemente:

CREATE EXTENSION tablefunc;

Para versiones anteriores, eche un vistazo a esta respuesta relacionada .

Consulta

La consulta podría verse así:

SELECT * FROM crosstab ( ''SELECT l.id ,c.column_name ,c.data FROM custom_columns_table c JOIN list_table l ON l.id = c.list_id ORDER BY 1'', ''SELECT DISTINCT column_name FROM custom_columns_table ORDER BY 1'') AS tbl ( id integer ,email text ,name text );

Utilizo la forma de crosstab() con dos parámetros, porque eso permite los atributos que faltan. Como, cuando una persona no tiene correo electrónico. Entonces este formulario devolverá NULL para la columna de email . Explicación detallada:

Función

O cree una función para que no tenga que proporcionar una lista de definición de columna para cada llamada:

CREATE OR REPLACE FUNCTION f_mycross(text, text) RETURNS TABLE ( id integer ,email text ,name text) AS ''$libdir/tablefunc'',''crosstab_hash'' LANGUAGE C STABLE STRICT;

Llamada:

SELECT * FROM f_mycross( ''SELECT l.id ,c.column_name ,c.data FROM custom_columns_table c JOIN list_table l ON l.id = c.list_id ORDER BY 1'', ''SELECT DISTINCT column_name FROM custom_columns_table ORDER BY 1'')