Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Concatenar varios registros (https://www.clubdelphi.com/foros/showthread.php?t=68697)

mjjj 30-06-2010 22:48:46

Concatenar varios registros
 
Hola gente del foro, tal como dice el titulo necesito concatenar varios registros en uno.

Utilizo Firebird 2.0.

Tengo 2 tablas, compras (noc:integer, area: string, proveedor:string) y detcompras(noc:integer, ncorr:integer, descripcion: string)

Ocurre que por cada registro de la tabla compras existe al menos 1 en la tabla detcompras.

Necesito hacer una consulta tal que me arroje todos los registros de la tabla compras (noc, area y proveedor), y adicionalmente en un solo campo todos las descripciones de la tabla detcompras.

Por ejemplo.

tabla compra:
registro 1: noc, area, proveedor --> 4, PROYECTO, JUAN
registro 2: noc, area, proveedor --> 5, EXISTENCIA, PEDRO

tabla detcompras:
registro 1: noc, ncorr, descripcion --> 4, 1, mas
registro 1: noc, ncorr, descripcion --> 5, 1, prueba
registro 2: noc, ncorr, descripcion --> 5, 2, clavo
registro 3: noc, ncorr, descripcion --> 5, 3, cosas

Lo que necesito es que mi consulta me arroje lo siguiente:

registro 1: noc, area, proveedor, detalle --> 4, PROYECTO, JUAN, mas
registro 2: noc, area, proveedor, detalle --> 5, EXISTENCIA, PEDRO, prueba clavo cosas

Espero se entienda.

Saludos

urixiv 01-07-2010 10:21:21

Hola,
primero de todo decirte que no se si en Firebird se puede hacer o no, pero te comento como lo haría yo con SQL Server.
Crearía una tabla temporal en ejecución, en la que con un cursor, iria recorriendo tu tabla Detcompras e iria concatenando los strings de cada producto.
Es decir en esta tabla guardaria tu campo noc y el string concatenado.
Para concatenarlo iria haciendo updates en esta tabla temporal.
Luego solo te quedaria hacer la select normal, haciendo join contra esta tabla temporal para tener los datos como los quieres.

Como te comento, esto en SQL Server se puede hacer, me imagino que con Firebird tambien. Seguro que hay alguna implementación más eficiente, pero ahora no se me ocurre!

Espero haberte ayudado o al menos haberte dado una pista de para donde tirar

Neftali [Germán.Estévez] 01-07-2010 10:44:21

No se si con una consulta sólo vas a poder hacerlo. Me da la impresión de que va a necesitar un Stored para hacer el recorrido y guardar las descripciones en el campo.

cloayza 01-07-2010 17:58:05

Podria ser asi:
Código SQL [-]
CREATE PROCEDURE spComprasDetalle
RETURNS(NOC INTEGER,
AREA VARCHAR(30),
PROVEEDOR VARCHAR(30),
DETALLE VARCHAR(200)) 
--Los largos de las variables debes definirlas de acuerdo a tus campos.

AS
DECLARE VARIABLE strDetalle VARCHAR(30);
BEGIN
      FOR SELECT NOC, AREA, PROVEEDOR
             FROM COMPRA
             INTO :NOC, :AREA,:PROVEEDOR
      DO
      BEGIN
              --Busca los detalles de DetCompras
              DETALLE='';
              FOR SELECT DESCRIPCION
                    FROM DETCOMPRAS
                    WHERE DETCOMPRAS.NOC=:NOC
                    INTO :strDetalle
              DO
              BEGIN
                      --Concatena los detalles
                      DETALLE=DETALLE||' '||strDetalle;
              END     

              SUSPEND;
      END
END;

NOTA: Este codigo no esta probado.

mjjj 01-07-2010 18:21:04

Creo que esto lo tengo que resolver con un proceso almacenado, donde le defino una variable de entrada com integer igual al numero de orden de compra. Algo así.

Código SQL [-]
create or alter procedure PRUEBA2 (
    NUMERO integer)
returns (
    NOC integer,
    FINAL varchar(200))
as
declare variable TOTAL varchar(200);
declare variable DESCRIP varchar(200);
begin
for select descrip_ins from DETCOMPRAS where NOC = :numero
into :DESCRIP do
begin
total = :DESCRIP ||' '|| :descrip;
end
for select noc,  :total from COMPRAS where NOC = :numero
into :noc,  :final do
begin
suspend;
end
end

Por ejmplo en la tabla detcompras tengo 23 registros de la ordenn numero 5, al correr este procedimiento, me repite la descripción del ultimo registro por 3 veces, el primero y el segundo nada.

Porque podrá ser esto?
Cual podría ser la forma correcta de hacer este procedimiento?

Espero me puedan ayudar.

Gracias

cloayza 01-07-2010 21:31:39

Al parecer no viste el codigo que te escribi mas arriba.

Saludos

mjjj 01-07-2010 21:56:56

No me di cuenta del nuevo post.

Gracias, funciono perfecto. Una sola cosa, es un detalle, pero si se pudiese solucionar ideal.

Lo que me arroja el resultado del procedimiento en el parametro de salida "detalle", se tiene un un separador " ", entre las distintas cadenas de los registros, el problema es que este separador también me lo incluye antes del primer registro.

Gracias, por todo.

Saludos

cloayza 01-07-2010 23:35:19

Podrias incorporar una verificacion del largo de la variable DETALLE...

Código SQL [-]
 --Concatena los detalles
IF (CHAR_LENGTH(DETALLE)=0) THEN
   DETALLE=strDetalle;
ELSE
   DETALLE=DETALLE||' '||strDetalle;

Saludos


La franja horaria es GMT +2. Ahora son las 16:58:27.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi