TRANSFORM plpgsql

From: "Jose Ayala - INCALPACA TPX" <jayala(at)incalpaca(dot)com>
To: "Edwin Quijada" <listas_quijada(at)hotmail(dot)com>
Cc: <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: TRANSFORM plpgsql
Date: 2005-03-28 14:17:50
Message-ID: 029801c533a0$ecac5cb0$140b0a09@sistem03
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

CREATE OR REPLACE FUNCTION "public"."transformstr2" (text, text, text, text,
text, text) RETURNS text AS'
declare
rec record; --record type for et returning
pivot_col alias for $1; -- What column must we pivot on?
qry_data alias for $2; -- query that contains data ..
headers alias for $3; -- headers to use ..
hd_col_name alias for $4; -- column of original table that contain the
headers of the new table ..
sum_val alias for $5; -- what to sum up
nullval alias for $6; -- what to use as null value ..
inner_sql text; -- internal sql query
outer_sql text; -- external sql query
headers_len int; -- length of the headers sting
headers_cnt int; -- this is the counter we use while going through the
headers csv string
test int; -- only for testing purposes..
headers_separator text; --what separator to use for the csv of the headers
(default: ";" (semicolon))
cur_separator text; -- This is the current position in the headers csv
string
last_separator int; -- this is to remember where the last separator was (the
last ;)
col_val text; -- this is where we store the value of the column that has to
become the header of the new table.
sql_string text; -- this is the whole sql string that will produce the
result of the crosstab query
begin
headers_cnt := 1;
test := 0;
headers_separator := '';''; -- this is the separator of the pivot columns ..
cur_separator := 0; -- initialize
last_separator := 0; -- initialize
inner_sql := ''''; -- initialize
outer_sql := ''''; --initialize
sql_string := ''''; --initialize
-- ---------------- BUILD SQL STRINGS ----------------------------
-- Split the csv names of cols ..
-- Length of string
headers_len := length(headers);
while headers_cnt <= headers_len loop
-- if the next character is ; then proceed
if substr(headers, headers_cnt, 1) = headers_separator then
-- we have a ";" so lets start
-- build the first part of inner_sql (the case whens ..)
-- store the name of the header col ..
col_val := substr(headers,last_separator + 1, headers_cnt -1 -
last_separator);
-- inner_sql := inner_sql || col_val || '' '';
inner_sql := inner_sql || ''case when '' || hd_col_name || ''='' || chr(39)
|| col_val || chr(39) || '' then '';
inner_sql := inner_sql || ''sum('' || sum_val || '') else '';
inner_sql := inner_sql || nullval || '' end as '' || col_val || '','';

-- build the outer_sql .. the second query to actually group everything up
outer_sql := outer_sql || ''sum(''|| col_val || '') as '' || col_val ||
'','';

-- remember position of previous ";"
last_separator := headers_cnt ;
end if;
-- increment the counter ..
headers_cnt := headers_cnt + 1;
end loop;
-- -------------------INNER SQL----------------------------
-- remove the last comma from the end of the cases ..
inner_sql := trim(trailing '','' from inner_sql);
-- now build the actual SQL string
inner_sql := ''SELECT '' || pivot_col || '','' || inner_sql || '' from '';
inner_sql := inner_sql || ''('' || qry_data || '') as foo GROUP BY '' ||
pivot_col || '','' || hd_col_name;
-- -------------------INNER SQL----------------------------
-- -------------------OUTER SQL----------------------------
-- trim the las comma from outer_sql
outer_sql := trim(trailing '','' from outer_sql);
-- build the string
outer_sql := ''SELECT '' || pivot_col || '','' || outer_sql || '' FROM ('';
-- -------------------OUTER SQL----------------------------
-- -----------------FULL SQL STRING----------------------------
sql_string := sql_string || outer_sql || inner_sql;
sql_string := sql_string || '') as bar group by '' || pivot_col;
-- -----------------FULL SQL STRING----------------------------

-- ---------------- BUILD SQL STRINGS ----------------------------
return sql_string;
end;
'LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

----- Original Message -----
From: "Edwin Quijada" <listas_quijada(at)hotmail(dot)com>
To: <jayala(at)incalpaca(dot)com>
Cc: <pgsql-es-ayuda(at)postgresql(dot)org>
Sent: Monday, March 28, 2005 8:29 AM
Subject: Re: [pgsql-es-ayuda] Varias cuestiones relacionadas con PostgreSQL

> Interesante! SI esta hecha en plpgsql puedes postearla.
> Por lo general, yo hago esto desde el cleinte
>
> *-------------------------------------------------------*
> *-Edwin Quijada
> *-Developer DataBase
> *-JQ Microsistemas
> *-809-747-2787
> * " Si deseas lograr cosas excepcionales debes de hacer cosas fuera de lo
> comun"
> *-------------------------------------------------------*
>
>
>
>>From: "Jose Ayala - INCALPACA TPX" <jayala(at)incalpaca(dot)com>
>>To: "Alvaro Herrera" <alvherre(at)dcc(dot)uchile(dot)cl>,Jairo Martín Miguel
>><jairo010(at)hotmail(dot)com>
>>CC: <pgsql-es-ayuda(at)postgresql(dot)org>
>>Subject: Re: [pgsql-es-ayuda] Varias cuestiones relacionadas con
>>PostgreSQL
>>Date: Wed, 23 Mar 2005 18:42:22 -0500
>>
>>Solo pa decir que aqui hemos logrado hacer una funcion que trabaja igual
>>que el TRANSFORM de Access o MSSQL, si desean la posteo.
>>
>>Slds
>>
>>Jose J. Ayala Pineda
>>Sistemas e Informatica
>> Incalpaca TPX S.A.
>> www.incalpaca.com
>>
>>
>>----- Original Message ----- From: "Alvaro Herrera"
>><alvherre(at)dcc(dot)uchile(dot)cl>
>>To: "Jairo Martín Miguel" <jairo010(at)hotmail(dot)com>
>>Cc: <pgsql-es-ayuda(at)postgresql(dot)org>
>>Sent: Wednesday, March 23, 2005 5:28 PM
>>Subject: Re: [pgsql-es-ayuda] Varias cuestiones relacionadas con
>>PostgreSQL
>>
>>
>>>On Wed, Mar 23, 2005 at 08:28:34PM +0100, Jairo Martín Miguel wrote:
>>>
>>>Hola,
>>>
>>>>Gracias por contestarme tan pronto. No utilizo My SQL porque no permite
>>>>consultas anidadas y no dispone de la sentencia TRANSFORM ni nada que se
>>>>le
>>>>parezca.
>>>
>>>No dije My SQL. Dije MS SQL Server.
>>>
>>>>La funcion transform coge por ejemplo una tabla con tres campos C1, C2 y
>>>>C3
>>>>y te devuelve los valores que le pidas en la sentencia
>>>
>>>Eso parece una trasposicion. La verdad, no conozco ninguna manera de
>>>hacerlo en Postgres de forma general. Hay una funcion llamada crosstab
>>>que quizas te sirva, o quizas no.
>>>
>>>En cualquier caso, estas cosas pueden escribirse en C de llegar a ser
>>>necesario.
>>>
>>>>Me gustaria estar seguro de lo de los campos en unicode, podrias
>>>>intentarlo??
>>>
>>>No, porque mi sistema no tiene como manejar Unicode (me mantengo lejos
>>>de eso como de la peste). Pero funciona con Latin1 (iso-8859-1), y
>>>Postgres maneja UTF-8 sin problemas, asi que supongo que deberia
>>>funcionar tambien con Unicode (en UTF-8 solamente ... si quieres UTF-16
>>>u otra cosa, creo que te va a costar un poco).
>>>
>>>alvherre=# create table álvaro ();
>>>CREATE TABLE
>>>alvherre=# \d
>>> Listado de relaciones
>>>Schema | Nombre | Tipo | Dueño
>>>--------+---------+-----------+----------
>>>public | álvaro | tabla | alvherre
>>>(1 filas)
>>>
>>>--
>>>Alvaro Herrera (<alvherre[(at)]dcc(dot)uchile(dot)cl>)
>>>"Aprender sin pensar es inútil; pensar sin aprender, peligroso"
>>>(Confucio)
>>>
>>>---------------------------(fin del mensaje)---------------------------
>>>TIP 4: No hagas 'kill -9' a postmaster
>>
>>
>>---------------------------(fin del mensaje)---------------------------
>>TIP 2: puedes desuscribirte de todas las listas simultáneamente
>> (envíe "unregister TuDirecciónDeCorreo" a majordomo(at)postgresql(dot)org)
>
> _________________________________________________________________
> Consigue aquí las mejores y mas recientes ofertas de trabajo en América
> Latina y USA: http://latam.msn.com/empleos/

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Damian Culotta 2005-03-28 18:23:21 pg_dumpall
Previous Message Juan Pablo Espino 2005-03-28 14:11:25 Re: Regla sobre tabla