Re: Unir varias tablas en un solo registro

Lists: pgsql-es-ayuda
From: MIGUEL CANCHAS <mcanchas(at)tsr(dot)com(dot)pe>
To: "'pgsql-es-ayuda(at)postgresql(dot)org'" <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Unir varias tablas en un solo registro
Date: 2008-03-27 18:58:17
Message-ID: 410117BB01F4D611B73A00010331DD2403B58AA2@tsnt.tsr.com.pe
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

Tengo 5 tablas y necesito que los datos vayan en un solo registro

Les muestro unos datos

Esta es la tabla principal
ficha_tejeduria
idficha idfamil iddescr
125 01 003

ficha_hilados
idficha porcentaje idhilo
125 20X 131
125 50X 172
125 30X 168

mfamilias
idfamil nomfamil
01 JERSEY

mdescripcion
iddescr nomdescr
003 SIMPLE

mhilos
idhilo titulo desc_hilo
131 19/1 COC
172 12/1 ALGOD. OPEN
168 24/75 COC

Asi deberia de quedar una combinacion.
idficha tela
125 JERSEY SIMPLE 20X 19/1 COC 50X 12/1 ALGOD. OPEN 30X 24/75 COC

Como podria empezar a hacerlo y si podria tenerlo en una vista seria mucho
mejor, aunque viendolo bien creo que solo podria ser con una funcion

Gracias

Miguel


From: "Calabaza Calabaza" <calalinux(at)gmail(dot)com>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Unir varias tablas en un solo registro
Date: 2008-03-27 21:58:58
Message-ID: 958993320803271458w28f65cexf09d8f09e1d60422@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

l 27/03/08, MIGUEL CANCHAS <mcanchas(at)tsr(dot)com(dot)pe> escribió:
> Tengo 5 tablas y necesito que los datos vayan en un solo registro
>
> Les muestro unos datos

> Esta es la tabla principal
Bueno, lo primero le puse alias a las tablas...

ficha_tejeduria a
idficha idfamil iddescr
125 01 003

ficha_hilados b
idficha porcentaje idhilo
125 20X 131
125 50X 172
125 30X 168

mfamilias c
idfamil nomfamil
01 JERSEY

mdescripcion d
iddescr nomdescr
003 SIMPLE

mhilos e
idhilo titulo desc_hilo
131 19/1 COC
172 12/1 ALGOD. OPEN
168 24/75 COC

> Asi deberia de quedar una combinacion.
> idficha tela
> 125 JERSEY SIMPLE 20X 19/1 COC 50X 12/1 ALGOD. OPEN 30X 24/75 COC

Luego hice la concatenacion de los campos, asumiendo que todos son de
tipo string...

Select
a.idficha,
c.nomfamil||' '||d.nomdescr||' '||b.porcentaje||' '||e.titulo||' '||e.desc_hilo
||' '||b.porcentaje||' '||e.titulo||' '||e.desc_hilo||'
'||b.porcentaje||' '||e.titulo||' '||e.desc_hilo as tela
from
ficha_tejeduria a
left join mfamilias c on (a.idfamil=c.idfamil)
left join ficha_hilados b on (a.idficha=b.idficha)
left join mdescripcion d on (a.iddescr=d.iddescr)
left join mhilos e on (b.idhilo=e.idhilo)

Pienso que aquí el problema es el from, tienes diferentes datos de la
misma tabla origen,
así como te lo puse pienso que te devolvería el mismo valor en las columnas

b.porcentaje||' '||e.titulo||' '||e.desc_hilo

O sea que o está faltando alguan tabla que no estas mostrando, o está
mal tu diseño de tu BD, podrías enviar una imagen de tu diagrama de
entidad / relación (DER) para ver como es la estructura?

> Como podria empezar a hacerlo

Mira como lo he hecho, si puedes corrigelo y nos cuentas, sino muestra
el DER a ver que esta faltando o para ver que esta mal diseñado..

> y si podria tenerlo en una vista seria mucho mejor,

Siempre puedes hacer una vista de una setencia select...

> aunque viendolo bien creo que solo podria ser con una funcion

Abría que verlo mejor!

> Gracias
Cuando quieras!
--
§~^Calabaza^~§ from Villa Elisa, Paraguay
----------------
A hendu hína: TIERRA SANTA - Leyenda
http://foxytunes.com/artist/tierra+santa/track/leyenda


From: "Calabaza Calabaza" <calalinux(at)gmail(dot)com>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Unir varias tablas en un solo registro
Date: 2008-03-27 22:19:19
Message-ID: 958993320803271519m6e7cab05h5167b664055772a9@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

Estuve reordenando los datos y entendí mejor tu estructura,
idficha tela
125 JERSEY SIMPLE
20X 19/1 COC
50X 12/1 ALGOD. OPEN
30X 24/75 COC

Creo que una tela tiene varios hilados y un hilado tiene un hilo?

prueba esto a ver que sale:

Select
a.idficha,
c.nomfamil||' '||d.nomdescr||' '||

array(Select
z.porcentaje||' '||x.titulo||' '||x.desc_hilo as hilado_con_hilo
from
ficha_hilados z left join mhilos x on (z.idhilo=x.idhilo)
where z.idficha=a.idficha)

as tela
from
ficha_tejeduria a
left join mfamilias c on (a.idfamil=c.idfamil)
left join mdescripcion d on (a.iddescr=d.iddescr)

Teóricamente debería devolver algo como:
idficha tela
125 JERSEY SIMPLE { 20X 19/1 COC,50X 12/1 ALGOD. OPEN,30X 24/75 COC}

El corchete {} es porque la funcion array()....
Lo que no estoy seguro es si se puede concatenar un array con un
string, ahora no lo puedo probar, pero al llegar a mi casa, me creo la
db de prueba y veo que tal sale...

Exitos!
--
§~^Calabaza^~§ from Villa Elisa, Paraguay
---------------
A hendu hína: TIERRA SANTA - Vikingos
http://foxytunes.com/artist/tierra+santa/track/vikingos


From: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
To: MIGUEL CANCHAS <mcanchas(at)tsr(dot)com(dot)pe>
Cc: "'pgsql-es-ayuda(at)postgresql(dot)org'" <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Unir varias tablas en un solo registro
Date: 2008-03-27 23:40:52
Message-ID: 20080327234052.GZ8764@alvh.no-ip.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

MIGUEL CANCHAS escribió:

> Asi deberia de quedar una combinacion.
> idficha tela
> 125 JERSEY SIMPLE 20X 19/1 COC 50X 12/1 ALGOD. OPEN 30X 24/75 COC
>
> Como podria empezar a hacerlo y si podria tenerlo en una vista seria mucho
> mejor, aunque viendolo bien creo que solo podria ser con una funcion

Es muy facil. Solo necesitas crear una funcion de agregacion propia
que concatene los textos que le entregues separandolos con un espacio.
No es ciencia de cohetes:

create or replace function concat(text, text) returns text
called on null input language plpgsql immutable
as $$
begin
if $1 is null then
return $2;
end if;
if $2 is null then
return $1;
end if;
return $1 || ' ' || $2;
end $$;

create aggregate text_concat (text) (sfunc = concat, stype = text);

Luego necesitas una consulta que obtenga todos los datos que te hacen
falta:

select a.idficha, nomfamil, nomdescr, porcentaje || ' ' || desc_hilo
from ficha_tejeduria a join
mfamilias b on (a.idfamil = b.idfamil) join
ficha_hilados c on (a.idficha = c.idficha) join
mdescripcion d on (a.iddescr = d.iddescr) join
mhilos e on (c.idhilo = e.idhilo)
where a.idficha = 125;

idficha | nomfamil | nomdescr | ?column?
---------+----------+----------+-----------------
125 | JERSEY | SIMPLE | 20X COC
125 | JERSEY | SIMPLE | 30X COC
125 | JERSEY | SIMPLE | 50X ALGOD. OPEN
(3 lignes)

Luego lo juntas todo con la funcion de agregacion que acabamos de crear:

select a.idficha, nomfamil, nomdescr, text_concat(porcentaje || ' ' || desc_hilo)
from ficha_tejeduria a join
mfamilias b on (a.idfamil = b.idfamil) join
ficha_hilados c on (a.idficha = c.idficha) join
mdescripcion d on (a.iddescr = d.iddescr) join
mhilos e on (c.idhilo = e.idhilo)
where a.idficha = 125
group by a.idficha, nomfamil, nomdescr;

idficha | nomfamil | nomdescr | text_concat
---------+----------+----------+---------------------------------
125 | JERSEY | SIMPLE | 20X COC 30X COC 50X ALGOD. OPEN
(1 ligne)

Si lo quieres en una vista, es facil:

create view tejidos as
select a.idficha, concat(concat(nomfamil, nomdescr), text_concat(porcentaje || ' ' || desc_hilo))
from ficha_tejeduria a join
mfamilias b on (a.idfamil = b.idfamil) join
ficha_hilados c on (a.idficha = c.idficha) join
mdescripcion d on (a.iddescr = d.iddescr) join
mhilos e on (c.idhilo = e.idhilo)
where a.idficha = 125
group by a.idficha, nomfamil, nomdescr;

select * from tejidos;

idficha | concat
---------+-----------------------------------------------
125 | JERSEY SIMPLE 20X COC 50X ALGOD. OPEN 30X COC
(1 ligne)

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


From: "Calabaza Calabaza" <calalinux(at)gmail(dot)com>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Unir varias tablas en un solo registro
Date: 2008-03-28 11:25:28
Message-ID: 958993320803280425p48c14701q10a89517269097ab@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

2008/3/27, Alvaro Herrera <alvherre(at)commandprompt(dot)com>:
> MIGUEL CANCHAS escribió:
>
>
> > Asi deberia de quedar una combinacion.
> > idficha tela
> > 125 JERSEY SIMPLE 20X 19/1 COC 50X 12/1 ALGOD. OPEN 30X 24/75 COC
> >
> > Como podria empezar a hacerlo y si podria tenerlo en una vista seria mucho
> > mejor, aunque viendolo bien creo que solo podria ser con una funcion
>
>
> Es muy facil. Solo necesitas crear una funcion de agregacion propia
> que concatene los textos que le entregues separandolos con un espacio.
> No es ciencia de cohetes:
>
> create or replace function concat(text, text) returns text
> called on null input language plpgsql immutable
> as $$
> begin
> if $1 is null then
> return $2;
> end if;
> if $2 is null then
> return $1;
> end if;
> return $1 || ' ' || $2;
> end $$;

Mejor explicado imposible!

Y esta linea que hace?

> create aggregate text_concat (text) (sfunc = concat, stype = text);

Entiendo que crea una función de agregación,
lo que no entiendo es el funcionamiento del create aggregate:

He mirado:
[1]http://www.postgresql.org/docs/7.4/interactive/sql-createaggregate.html

[1]"

CREATE AGGREGATE name (
BASETYPE = input_data_type,
SFUNC = sfunc,
STYPE = state_data_type
[ , FINALFUNC = ffunc ]
[ , INITCOND = initial_condition ]
)

An aggregate function is made from one or two ordinary functions: a
state transition function sfunc, and an optional final calculation
function ffunc. These are used as follows:

sfunc( internal-state, next-data-item ) ---> next-internal-state
ffunc( internal-state ) ---> aggregate-value

PostgreSQL creates a temporary variable of data type stype to hold the
current internal state of the aggregate. At each input data item, the
state transition function is invoked to calculate a new internal state
value. After all the data has been processed, the final function is
invoked once to calculate the aggregate's return value. If there is no
final function then the ending state value is returned as-is."

Y luego en la parte en que explica que significa cada palabra de la sintaxis:

"sfunc

The name of the state transition function to be called for each
input data value. This is normally a function of two arguments, the
first being of type state_data_type and the second of type
input_data_type. Alternatively, for an aggregate that does not examine
its input values, the function takes just one argument of type
state_data_type. In either case the function must return a value of
type state_data_type. This function takes the current state value and
the current input data item, and returns the next state value.
"

O sea que la función de agregación text_concat:

> create aggregate text_concat (text) (sfunc = concat, stype = text);

Haría lo siguiente?:

concat(valor_interno0, valor1)
--> sgte_valor
--> concat(sgte_valor, valor2)
--> sgte_valor
--> concat(sgte_valor, valorX)
--> valor_final

> Luego necesitas una consulta que obtenga todos los datos que te hacen
> falta:
>
> select a.idficha, nomfamil, nomdescr, porcentaje || ' ' || desc_hilo
> from ficha_tejeduria a join
> mfamilias b on (a.idfamil = b.idfamil) join
> ficha_hilados c on (a.idficha = c.idficha) join
> mdescripcion d on (a.iddescr = d.iddescr) join
> mhilos e on (c.idhilo = e.idhilo)
> where a.idficha = 125;
>
> idficha | nomfamil | nomdescr | ?column?
> ---------+----------+----------+-----------------
> 125 | JERSEY | SIMPLE | 20X COC
> 125 | JERSEY | SIMPLE | 30X COC
> 125 | JERSEY | SIMPLE | 50X ALGOD. OPEN
> (3 lignes)
>
> Luego lo juntas todo con la funcion de agregacion que acabamos de crear:
>
> select a.idficha, nomfamil, nomdescr, text_concat(porcentaje || ' ' || desc_hilo)
> from ficha_tejeduria a join
> mfamilias b on (a.idfamil = b.idfamil) join
> ficha_hilados c on (a.idficha = c.idficha) join
> mdescripcion d on (a.iddescr = d.iddescr) join
> mhilos e on (c.idhilo = e.idhilo)
> where a.idficha = 125
> group by a.idficha, nomfamil, nomdescr;
>
> idficha | nomfamil | nomdescr | text_concat
> ---------+----------+----------+---------------------------------
> 125 | JERSEY | SIMPLE | 20X COC 30X COC 50X ALGOD. OPEN
> (1 ligne)
>
>
> Si lo quieres en una vista, es facil:
>
> create view tejidos as
> select a.idficha,
> concat(concat(nomfamil, nomdescr), text_concat(porcentaje || ' ' || desc_hilo))

Definitivamente excelente solución! y muy útil!

> from ficha_tejeduria a join
> mfamilias b on (a.idfamil = b.idfamil) join
> ficha_hilados c on (a.idficha = c.idficha) join
> mdescripcion d on (a.iddescr = d.iddescr) join
> mhilos e on (c.idhilo = e.idhilo)
> where a.idficha = 125
> group by a.idficha, nomfamil, nomdescr;
>
>
> select * from tejidos;
>
> idficha | concat
> ---------+-----------------------------------------------
> 125 | JERSEY SIMPLE 20X COC 50X ALGOD. OPEN 30X COC
> (1 ligne)
>
>
> --
> Alvaro Herrera http://www.CommandPrompt.com/
> PostgreSQL Replication, Consulting, Custom Development, 24x7 support
>
> --
> TIP 1: para suscribirte y desuscribirte, visita http://archives.postgresql.org/pgsql-es-ayuda
>

Gracias Alvaro por esta excelente solución.
--
§~^Calabaza^~§ from Villa Elisa, Paraguay
----------------
A hendu hína: Tierra Santa - El Amor de Mi Vida
http://foxytunes.com/artist/tierra+santa/track/el+amor+de+mi+vida


From: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
To: Calabaza Calabaza <calalinux(at)gmail(dot)com>
Cc: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Unir varias tablas en un solo registro
Date: 2008-03-28 12:33:15
Message-ID: 20080328123315.GE7464@alvh.no-ip.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

Calabaza Calabaza escribió:

> He mirado:
> [1]http://www.postgresql.org/docs/7.4/interactive/sql-createaggregate.html

Es un poco añejo eso, y si te fijas no explica la sintaxis que yo usé,
porque en vez de BASETYPE el tipo del parámetro lo pasé de otra forma.

Máralo acá:
http://www.postgresql.org/docs/8.3/interactive/sql-createaggregate.html

> O sea que la función de agregación text_concat:
>
> > create aggregate text_concat (text) (sfunc = concat, stype = text);
>
> Haría lo siguiente?:
>
> concat(valor_interno0, valor1)
> --> sgte_valor
> --> concat(sgte_valor, valor2)
> --> sgte_valor
> --> concat(sgte_valor, valorX)
> --> valor_final

Justamente ... piensa que la función de agregación sum está definida
como

create aggregate sum (int) (sfunc = int4add, stype = int)

donde int4add sería la función que toma dos números y los suma.

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.


From: Julio Cesar Sánchez González <knowhow(at)sistemasyconectividad(dot)com(dot)mx>
To: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
Cc: MIGUEL CANCHAS <mcanchas(at)tsr(dot)com(dot)pe>, "'pgsql-es-ayuda(at)postgresql(dot)org'" <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Unir varias tablas en un solo registro
Date: 2008-03-30 06:52:57
Message-ID: 47EF38C9.4060006@sistemasyconectividad.com.mx
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

Alvaro Herrera wrote:
> MIGUEL CANCHAS escribió:
>
>
>> Asi deberia de quedar una combinacion.
>> idficha tela
>> 125 JERSEY SIMPLE 20X 19/1 COC 50X 12/1 ALGOD. OPEN 30X 24/75 COC
>>
>> Como podria empezar a hacerlo y si podria tenerlo en una vista seria mucho
>> mejor, aunque viendolo bien creo que solo podria ser con una funcion
>>
>
> Es muy facil. Solo necesitas crear una funcion de agregacion propia
> que concatene los textos que le entregues separandolos con un espacio.
> No es ciencia de cohetes:
>
> create or replace function concat(text, text) returns text
> called on null input language plpgsql immutable
> as $$
> begin
> if $1 is null then
> return $2;
> end if;
> if $2 is null then
> return $1;
> end if;
> return $1 || ' ' || $2;
> end $$;
>
> create aggregate text_concat (text) (sfunc = concat, stype = text);
>
> Luego necesitas una consulta que obtenga todos los datos que te hacen
> falta:
>
> select a.idficha, nomfamil, nomdescr, porcentaje || ' ' || desc_hilo
> from ficha_tejeduria a join
> mfamilias b on (a.idfamil = b.idfamil) join
> ficha_hilados c on (a.idficha = c.idficha) join
> mdescripcion d on (a.iddescr = d.iddescr) join
> mhilos e on (c.idhilo = e.idhilo)
> where a.idficha = 125;
>
> idficha | nomfamil | nomdescr | ?column?
> ---------+----------+----------+-----------------
> 125 | JERSEY | SIMPLE | 20X COC
> 125 | JERSEY | SIMPLE | 30X COC
> 125 | JERSEY | SIMPLE | 50X ALGOD. OPEN
> (3 lignes)
>
> Luego lo juntas todo con la funcion de agregacion que acabamos de crear:
>
> select a.idficha, nomfamil, nomdescr, text_concat(porcentaje || ' ' || desc_hilo)
> from ficha_tejeduria a join
> mfamilias b on (a.idfamil = b.idfamil) join
> ficha_hilados c on (a.idficha = c.idficha) join
> mdescripcion d on (a.iddescr = d.iddescr) join
> mhilos e on (c.idhilo = e.idhilo)
> where a.idficha = 125
> group by a.idficha, nomfamil, nomdescr;
>
> idficha | nomfamil | nomdescr | text_concat
> ---------+----------+----------+---------------------------------
> 125 | JERSEY | SIMPLE | 20X COC 30X COC 50X ALGOD. OPEN
> (1 ligne)
>
>
> Si lo quieres en una vista, es facil:
>
> create view tejidos as
> select a.idficha, concat(concat(nomfamil, nomdescr), text_concat(porcentaje || ' ' || desc_hilo))
> from ficha_tejeduria a join
> mfamilias b on (a.idfamil = b.idfamil) join
> ficha_hilados c on (a.idficha = c.idficha) join
> mdescripcion d on (a.iddescr = d.iddescr) join
> mhilos e on (c.idhilo = e.idhilo)
> where a.idficha = 125
> group by a.idficha, nomfamil, nomdescr;
>
>
> select * from tejidos;
>
> idficha | concat
> ---------+-----------------------------------------------
> 125 | JERSEY SIMPLE 20X COC 50X ALGOD. OPEN 30X COC
> (1 ligne)
>
>
>
Hola a todos, me parecio muy interesante esta solucion empleando
funciones agregadas, en donde puedo encontrar mas informacion al
respecto fuera de la documentacion del manual que ya estoy leyendo. Si
es posible algunos ejemplos mas me daria por mas que bien servido.

De antemano muchas gracias.

--
Saludos,

Julio Cesar Sánchez González.

--
Ahora me he convertido en la muerte, destructora de mundos.
Soy la Muerte que se lleva todo, la fuente de las cosas que vendran.

www.sistemasyconectividad.com.mx http://darkavngr.blogspot.com/


From: "Calabaza Calabaza" <calalinux(at)gmail(dot)com>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Unir varias tablas en un solo registro
Date: 2008-03-31 11:00:31
Message-ID: 958993320803310400l4a093e32n1b69b4a9407c807d@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-es-ayuda

2008/3/30, Julio Cesar Sánchez González <knowhow(at)sistemasyconectividad(dot)com(dot)mx>:

> Hola a todos, me parecio muy interesante esta solucion empleando
> funciones agregadas, en donde puedo encontrar mas informacion al

> respecto fuera de la documentacion del manual que ya estoy leyendo.

Como qué esperas encontrar?
Creo que ahí esta muy bien explicado,
salvo que tu ingles no ande tan bien, entonces pides ayuda aquí y listo!

> Si
> es posible algunos ejemplos mas me daria por mas que bien servido.

http://www.postgresql.org/docs/8.3/interactive/xaggr.html

Este es el link de los ejemplos, míralos a ver que tal....

> De antemano muchas gracias.

Ok, fuerza!

--
§~^Calabaza^~§ from Villa Elisa, Paraguay