Re: Unir varias tablas en un solo registro

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
Thread:
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

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Ana Smail 2008-03-28 11:42:36 RE: restringir privilegios a un usuario
Previous Message Miguel Rodríguez Penabad 2008-03-28 08:31:52 Re: Detalles de MySQL, para quien le interese...