Ir al contenido


Foto

unir dos sql


  • Por favor identifícate para responder
1 respuesta en este tema

#1 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 30 junio 2012 - 01:01

Hola a todos
tengo dos sentencias sql, cada uno por separado funciona muy bien.
las dos me dan un resultado muy parecido, la diferencia esta en las tablas.
Esta es la primera:
SELECT DISTINCT  matextra.descripcion, sum(matextra.cantidad) as cantidad
from matextra
where matextra.Fecha >= :f1 AND matextra.Fecha <= :f2
group by matextra.descripcion

me envia este resultado, la descripcion y la suma de cantidad:

DESCRIPCION---------- CANTIDAD
FIBRA MAT 1 1/2 KL---------- 4
FIBRA MAT 3/4  KL----------- 1
FIBRA ROV 2400  KILOS---- 7.35
RESINA 277  KILOS---------- 10.5
RESINA CARGA---------------- 8.5

Esta es la segunda:
SELECT Tabla1.CodMaterial, Tabla1.Descripcion, Tabla1.Costo,
Sum(Cantidad) AS Exp2,  Sum(Tabla1.Costo*Cantidad) AS Exp1
FROM
(SELECT SerieMaterial.CodMaterial, Materiales.Descripcion, SerieMaterial.Cantidad,
Materiales.Costo, OrdenProdItem.FinProd
FROM Materiales RIGHT JOIN (OrdenProdItem INNER JOIN SerieMaterial
ON OrdenProdItem.NumSerie = SerieMaterial.NumSerie) ON Materiales.CodMaterial = SerieMaterial.CodMaterial
WHERE (OrdenProdItem.FinProd >= :Fecha1 AND OrdenProdItem.FinProd <= :Fecha2) AND SerieMaterial.Cantidad >0
ORDER BY SerieMaterial.CodMaterial) AS Tabla1
GROUP BY Tabla1.CodMaterial, Tabla1.Descripcion, Tabla1.Costo;

Me muestra esto:

CODMATERIAL------- DESCRIPCION------------ COSTO--- EXP2----- EXP1
CMEK------------------ CATALIZADO-MEK--- 10600---- 45.805--- 485533
FV115----------------- FIBRA MAT 1 1/2 KL--- 1300----- 29.08---- 37804
FV34K----------------- FIBRA MAT 3/4  KL--- 1300----- 8.15------ 10608
G120CFCL------------ GEL CAFE MADERA--- 3190----- 2---------- 6380
R2400----------------- FIBRA ROV 2400  KILOS-- 1060----- 589.8---- 625188
RCCFB----------------- RESINA CARGA---- 1032----- 2208.4--- 2279068.8


EXP2 es el dato de la cantidad.
Lo que me gustaria es que me sumara el dato de la cantidad de las dos tablas y me lo mostrara en una sola columna.
Gracias de antemano.
Saludos
  • 0

#2 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 02 julio 2012 - 03:00

Pues es sencillo, a tu Exp2 le sumas el primer select completo, limpiandolo antes para eliminar la descripcion, unir las dos descripciones de las dos SQL, e igualar los parámetros de fechas:


SELECT
  Tabla1.CodMaterial, Tabla1.Descripcion, Tabla1.Costo,
  SUM(Cantidad) + (SELECT SUM(matextra.cantidad) FROM matextra
  WHERE matextra.descripcion=Tabla1.Descripcion AND matextra.Fecha >= :Fecha1 AND matextra.Fecha <= :Fecha2) AS Exp2,
  SUM(Tabla1.Costo*Cantidad) AS Exp1
FROM
  (SELECT SerieMaterial.CodMaterial, Materiales.Descripcion, SerieMaterial.Cantidad,
  Materiales.Costo, OrdenProdItem.FinProd
  FROM Materiales
  RIGHT JOIN (OrdenProdItem INNER JOIN SerieMaterial ON OrdenProdItem.NumSerie = SerieMaterial.NumSerie)
  ON Materiales.CodMaterial = SerieMaterial.CodMaterial
  WHERE (OrdenProdItem.FinProd >= :Fecha1 AND OrdenProdItem.FinProd <= :Fecha2) AND SerieMaterial.Cantidad >0
ORDER BY SerieMaterial.CodMaterial) AS Tabla1
GROUP BY Tabla1.CodMaterial, Tabla1.Descripcion, Tabla1.Costo;


Lo de hacer un selec sobre otro select parece redundante, y además con dos join dentro anidados, buf! que poco claro queda el código (o que poco acostumbrado estoy).

Eso es muy mala cosa porque el optimizador de consultas de FB no va a poder optimizar nada, y la diferencia puede ser brutal.

Como no siguo muy bien la SQL, te intento "desenredar" la estructur,a pero supongo que no funcionara, es solo para comparar:


SELECT
  SM.CodMaterial, M.Descripcion, M.Costo,
  SUM(SM.Cantidad) + (SELECT SUM(ME.cantidad) FROM MatExtra ME
  WHERE ME.descripcion=M.Descripcion AND ME.Fecha BETWEEN :Fecha1 AND :Fecha2) AS Exp2,
  SUM(M.Costo*SM.Cantidad) AS Exp1
FROM Materiales M
  INNER JOIN SerieMaterial SM ON M.CodMaterial = SM.CodMaterial 
  RIGHT JOIN OrdenProdItem OPI ON OPI.NumSerie = SM.NumSerie
WHERE (OPI.FinProd BETWEEN :Fecha1 AND :Fecha2) AND (SM.Cantidad >0)
GROUP BY SM.CodMaterial, M.Descripcion, M.Costo;


Como ves, es mejor un FROM y luego una lista de JOINs, no anidar 2 select si no hace falta, y usar una o dos letras para cada tabla... ha, y si haces group by se ordena por eso mismo, por lo que el ORDER BY te "sobraba".

Esto hace todo mas claro... por ejemplo, ahora se ve que filtras por cosas que NO son de material, son fechas de OPI, así que interesa que el FROM sea del OPI, se optimiza un disparate (FB 2.5 mejoro esto pero siempre es mejor darselo ya "pensado").

Sería mas eficiente así:


SELECT
  SM.CodMaterial, M.Descripcion, M.Costo,
  SUM(SM.Cantidad) + (SELECT SUM(ME.cantidad) FROM MatExtra ME
  WHERE ME.descripcion=M.Descripcion AND ME.Fecha BETWEEN :Fecha1 AND :Fecha2) AS Exp2,
  SUM(M.Costo*SM.Cantidad) AS Exp1
FROM  OrdenProdItem OPI
  INNER JOIN SerieMaterial SM ON (SM.NumSerie = OPI.NumSerie) AND (SM.Cantidad >0)
  LEFt JOIN Materiales M ON M.CodMaterial = SM.CodMaterial
WHERE (OPI.FinProd BETWEEN :Fecha1 AND :Fecha2)
GROUP BY SM.CodMaterial, M.Descripcion, M.Costo;


Así ya me gusta... bueno, sigo sin ver claro el que la tabla MatExtra la unas por la descripcion y no por un numero de serie que tenga indice creado, eso puede arruinar el rendimiento de la SQL global.
  • 0




IP.Board spam blocked by CleanTalk.