Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Tablas planas (https://www.clubdelphi.com/foros/forumdisplay.php?f=20)
-   -   Unir dos tablas sin relación (https://www.clubdelphi.com/foros/showthread.php?t=95801)

GINMARMENOR 28-08-2022 01:13:22

Unir dos tablas sin relación
 
Tengo dos tablas creadas en Firebird (*.FDB), quiero unirlas para sacar un informe pero me encuentro con el siguiente problema, como es un poco complicado expresarlo os lo pongo en un ejemplo, esta tabla sería la original:

Código Delphi [-]
                
                  TABLA PEDIDOS                                    TABLA COMPRAS
             
   ID   CODIGO    NOMBRE         CANTIDAD                    ID  CODIGO      NOMBRE         CANTIDAD

    1       A001   TORNILLOS A      5.000                     1    A002     ARANDELAS A      20.000
    2       A002   ARANDELAS A      6.000                     2    A001     TORNILLOS A      15.000
    3       A003   TUERCAS A        4.000                     3    A002     ARANDELAS A      20.000
    4       A001   TORNILLOS A      4.000                     4    A003     TUERCAS A        15.000
    5       A002   ARANDELAS A      3.000                     5    A001     TORNILLOS A      25.000

Lo que hago mediante SQL, es intentar filtrar la tabla pedidos y compras y filtrar por el codigo A001 (TORNILLOS A) y obtener en un informe la cantidad de pedidos y comprados de este artículo, el codigo que utilizo para esto es


Código SQL [-]
            select * from pedidos inner join compras on pedidos.id=Compras.Id where pedidos.id=' + 
            Quotedstr('A001') + 'and Compras.Id=' + Quotedstr('A001')

De esta informe que lo hago en Rave Reports, me sale de la siguiente manera no sale nada por que no coincidente al filtrar un mismo registro con los id iguales.

Si el código SQL es el siguiente:
Código SQL [-]
select * from pedidos inner join compras on pedidos.id=Compras.Id where pedidos.id=' + 
            Quotedstr('A001');

El informe es el siguiente:
Código Delphi [-]
                TABLA PEDIDOS                                    TABLA COMPRAS
             
   ID   CODIGO    NOMBRE         CANTIDAD                    ID  CODIGO      NOMBRE         CANTIDAD

    1       A001   TORNILLOS A      5.000                     1    A002     ARANDELAS A      20.000    
    4       A001   TORNILLOS A      4.000                     4    A003     TUERCAS A        15.000

También seria igual si el código es left join, y y si con right join.

El informe sería:
Código Delphi [-]
 ID   CODIGO    NOMBRE         CANTIDAD              ID  CODIGO      NOMBRE         CANTIDAD
    
    2       A002   ARANDELAS A      6.000             2    A001     TORNILLOS A      15.000 
    5       A002   ARANDELAS A      3.000             5    A001     TORNILLOS A      25.000
Si lo filtro por la tabla compras me arrastra los datos del mismo registro de la tabla Pedidos y al revés y sólo busco que me filtre en ambas tablas las que son iguales al código que espefico.

Lo he intentado con Inner Outer Join, y con las distintas formas de SQL JOINS SQL Joins

Mi intención es poder sacar el siguiente informe:

Código Delphi [-]
            TABLA PEDIDOS                                    TABLA COMPRAS
             
   ID   CODIGO    NOMBRE         CANTIDAD      ID  CODIGO      NOMBRE         CANTIDAD

    1       A001   TORNILLOS A      5.000        2    A001     TORNILLOS A      15.000                                                                              
    4       A001   TORNILLOS A      4.000        5    A001     TORNILLOS A      25.000

Donde puedo ver los Tornillos pedidos y Comprados en un sólo informe, pero no encuentro la manera de filtrar ambas tablas y unirlas en este informe.

Casimiro Notevi 28-08-2022 10:01:20

¿Pero exactamente qué quieres hacer?

duilioisola 28-08-2022 10:19:48

No entiendo bién que es lo que quieres hacer, pero creo que la solución a tu cuestión es utilizar UNION.
Código SQL [-]
/*
Devuelve los campos ID, CODIGO, NOMBRE, CANTIDAD 
de las tablas PEDIDOS y COMPRAS 
cuyo CODIGO='A001'
*/
SELECT id, codigo, nombre, cantidad
FROM PEDIDOS
WHERE
codigo = 'A001'
UNION ALL
SELECT id, codigo, nombre, cantidad
FROM COMPRAS
WHERE
codigo = 'A001'

Si las tablas contienen
Código:

                  TABLA PEDIDOS                                    TABLA COMPRAS
           
  ID  CODIGO    NOMBRE        CANTIDAD                    ID  CODIGO      NOMBRE        CANTIDAD

    1      A001  TORNILLOS A      5.000                    1    A002    ARANDELAS A      20.000
    2      A002  ARANDELAS A      6.000                    2    A001    TORNILLOS A      15.000
    3      A003  TUERCAS A        4.000                    3    A002    ARANDELAS A      20.000
    4      A001  TORNILLOS A      4.000                    4    A003    TUERCAS A        15.000
    5      A002  ARANDELAS A      3.000                    5    A001    TORNILLOS A      25.000

deolvería

Código:

  ID  CODIGO    NOMBRE        CANTIDAD

    1    A001  TORNILLOS A      5.000
    4    A001  TORNILLOS A      4.000
    2    A001  TORNILLOS A      15.000
    5    A001  TORNILLOS A      25.000

Nota:
La instrucción UNION puede tener dos formas
UNION : Si un registro se repite solo devuelve uno.
Si tanto en la tabla de pedidos como en compras hubiera un registro 1,'A001', TORNILLOS A, 10,000 te deolvería una sola línea

UNION ALL : Devuelve todos los registros aunque estén repetidos.
Si tanto en la tabla de pedidos como en compras hubiera un registro 1,'A001', TORNILLOS A, 10,000 te deolvería dos líneas)

Nota 2:
Puedes agregar un campo fijo para saber el origen de cada dato. De lo contrario no sabrás si el ID se refiere al ID de una tabla o de otra
Código SQL [-]
/*
Devuelve los campos ID, CODIGO, NOMBRE, CANTIDAD 
de las tablas PEDIDOS y COMPRAS 
cuyo CODIGO='A001'
*/
SELECT 'PED' as tipo, id, codigo, nombre, cantidad
FROM PEDIDOS
WHERE
codigo = 'A001'
UNION ALL
SELECT 'COM' as tipo, id, codigo, nombre, cantidad
FROM COMPRAS
WHERE
codigo = 'A001'

/*
Devuelve
    TIPO  ID   CODIGO    NOMBRE         CANTIDAD

    PED    1    A001   TORNILLOS A      5.000
    PED    4    A001   TORNILLOS A      4.000
    COM    2    A001   TORNILLOS A      15.000
    COM    5    A001   TORNILLOS A      25.000
*/

GINMARMENOR 28-08-2022 19:29:54

duilioisol me sale todo como dices la tabla perfecto, para este caso utiliza UNION en vez de UNION ALL, miles de gracias.

pero lo único que no consigo introducir los datos en el campo (TIPO) para diferenciar si es de una tabla u otra, ya que lo hago en modo diseño por que tengo que pasar por 'SQl.Txt:=' '':



/*
sql.text:=' SELECT 'PED' as tipo, id, codigo, nombre, cantidad
FROM PEDIDOS
WHERE
codigo = 'A001'
UNION
SELECT 'COM' as tipo, id, codigo, nombre, cantidad
FROM COMPRAS
WHERE
codigo = 'A001' '
*/

He intentado miles de formas pero al usar las comillas no lo puedo hacer, no consigo insertar los datos.

Casimiro Notevi 28-08-2022 21:06:59

Hay varias formas, lo mejor es usar parámetros.
De todas formas prueba a usar la comilla doble "

GINMARMENOR 28-08-2022 22:23:39

No tampoco con doble comillas funciona da error
Código Delphi [-]
/*
sql.text:=' SELECT "PED" as tipo, id, codigo, nombre, cantidad
FROM PEDIDOS
WHERE
codigo = 'A001'
UNION
SELECT "COM" as tipo, id, codigo, nombre, cantidad
FROM COMPRAS
WHERE
codigo = 'A001' '
*/
Por internet no encuentro nada que pueda unir dos tablas y además insertar datos fijos en un campo, con esta sintaxis.

Casimiro Notevi 28-08-2022 22:49:20

Ahí no, en el parámetro:
Código Delphi [-]
codigo = "A001" '
Y por cierto, no olvides usar las etiquetas para código, gracias.

duilioisola 29-08-2022 08:36:50

He intentado miles de formas pero al usar las comillas no lo puedo hacer, no consigo insertar los datos.

¿Cuál es el mensaje de error?

Si es un error de Delphi que te impide compilar y dice alg así como que "la línea no termina" debes seguir haciéndolo como hasta ahora lo hacías (Según tu ejemplo anterior)

Código Delphi [-]
SQL.Text := 'select * from pedidos inner join compras on pedidos.id=Compras.Id where pedidos.id=' + Quotedstr('A001') + ' and Compras.Id=' + Quotedstr('A001');

Para enteder el tema:
1. Los strings en Delphi se determinan entre comillas simpels
Código Delphi [-]
s := 'Hello World';
wrilte(s);
Código:

=>Hello World
2. La forma de poner una comilla simple en un string en el codigo es repitiéndola
Código Delphi [-]
s := 'Hello ''World''';
wrilte(s);
Código:

=>Hello 'World'
3. Otra forma de hacer lo mismo es mediante la función QuoteStr
Código Delphi [-]
s := 'Hello ' + QuotedStr('World');
wrilte(s);
Código:

=>Hello 'World'

Yo suelo hacerlo de la siguiente manera para poder ver código SQL dentro de código Delphi facilmente:

Código Delphi [-]
// Cierro Dataset
// Asigno SQL
// Filtro por parámetro
// Abro Dataset
with DataSet do
begin
   Close;
   SQL.Clear;
   SQL.Add(' SELECT ''PED'' as tipo, id, codigo, nombre, cantidad ');
   SQL.Add(' FROM PEDIDOS ');
   SQL.Add(' WHERE ');
   SQL.Add(' codigo = :CODIGO ');
   SQL.Add(' UNION ');
   SQL.Add(' SELECT ''COM'' as tipo, id, codigo, nombre, cantidad ');
   SQL.Add(' FROM COMPRAS ');
   SQL.Add(' WHERE ');
   SQL.Add(' codigo = :CODIGO ');
   Params.ByName['CODIGO'].AsString := 'A001';
   Open;
   [...]
end;

Casimiro Notevi 29-08-2022 10:19:43

Es la mejor opción y la más profesional y segura.
Cita:

Empezado por duilioisola (Mensaje 548119)
Código Delphi [-]
SQL.Add(' codigo = :CODIGO ');
Params.ByName['CODIGO'].AsString := 'A001'

La opción de poner dobles comillas también funciona, aunque no me gusta.

GINMARMENOR 30-08-2022 20:36:32

Ok, funciona perfectamente, gracias por vuestra paciencia.


La franja horaria es GMT +2. Ahora son las 13:39:03.

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