Subconsultas

Necesito ejecutar una consulta de solo lectura, que consta a su vez de otras consultas y que encima tienen que ser parametrizadas.
Hasta ahora lo único que he conseguido es un procedimiento almacenado incluyendo las subconsultas de la forma: ... FROM (SELECT...)
Pero como son varias las subconsultas el procedimiento tarda bastante en ejecutar la consulta.

1 respuesta

Respuesta
1
La verdad, que con la información que me das no sé como aconsejarte. Habría que estudiar el diseño de las tablas donde tienes la información y la consulta en concreto, para ver si se puede mejorar.
Comentame un poco en que consiste y enviame un script de las tablas que intervienen y de la consulta. Con esto le echo un vistazo y te comento.
Ya lo he solucionado, pero no me gusta como queda, solo tarda 2 o 3 segundos en ejecutarse pero como tenga que hacer muchas consultas como estas me puedo morir.
Trabajo con Visual Basic 6.0 y SQL SERVER 7.0
Al final cree un procedimiento almacenado, ahí va:
CREATE PROCEDURE procBalanceObrasEnCurso
@F_Inicio varchar(10), @F_Fin varchar(10)
AS
SELECT q.Ref_OrFa, ISNULL(HR.H_R,0) as H_R, ISNULL(HR.VMHR,0) as VMHR,ISNULL(H_R * VMHR,0) as PtasH_R, Mat.PtasMateriales,
Fac.FacVent, q.Descripcion, q.Ptas_P, q.Empresa, TotalOF = ISNULL((HR.H_R * HR.VMHR),0)+ISNULL(Mat.PtasMateriales,0),
Neto = case
when ISNULL((HR.H_R * HR.VMHR),0)+ISNULL(Mat.PtasMateriales,0)+ISNULL(Fac.FacVent,0)>q.Ptas_P and q.Ptas_P>0 then q.Ptas_P- ISNULL(Fac.FacVent,0) else ISNULL((HR.H_R * HR.VMHR),0)+ISNULL(Mat.PtasMateriales,0)-ISNULL(Fac.FacVent,0) end
FROM
(SELECT O.Ref_OrFa, O.Descripcion, O.Ptas_P, C.Empresa,
O.Ref_O, O.Día_Entrega, O.Situación_O, O.Día_Apertura
FROM dbo.Ofertas O INNER JOIN
dbo.Clientes C ON O.IdCliente = C.IdCliente
WHERE (O.Situación_O = 'PED' OR
O.Situación_O = 'GAR' OR
O.Situación_O = 'ENT') AND
(O.Día_Entrega > CONVERT(DATETIME, @F_Inicio, 103) OR
O.Día_Entrega IS NULL) AND
(O.Día_Apertura < CONVERT(DATETIME, @F_Fin, 103) OR
O.Día_Apertura IS NULL)) q
LEFT OUTER JOIN
(SELECT q.Ref_O, SUM(facvent.bimpon * mon.cammon)
AS FacVent
FROM (SELECT O.Ref_OrFa, O.Descripcion, O.Ptas_P, C.Empresa,
O.Ref_O, O.Día_Entrega, O.Situación_O, O.Día_Apertura
FROM dbo.Ofertas O INNER JOIN
dbo.Clientes C ON O.IdCliente = C.IdCliente
WHERE (O.Situación_O = 'PED' OR
O.Situación_O = 'GAR' OR
O.Situación_O = 'ENT') AND
(O.Día_Entrega > CONVERT(DATETIME, @F_Inicio, 103) OR
O.Día_Entrega IS NULL) AND
(O.Día_Apertura < CONVERT(DATETIME, @F_Fin, 103) OR
O.Día_Apertura IS NULL)) q INNER JOIN
dbo.VentasPedidos V ON q.Ref_O = V.Oferta INNER JOIN
dbo.facvent ON
V.RegVentasPedidos = dbo.facvent.RegVentasPedidos INNER JOIN
(SELECT codmon, cammon
FROM gros.dbo.comon
WHERE (codemp = '006')) mon ON
dbo.facvent.codmon = mon.codmon
WHERE (dbo.facvent.fechafactura < CONVERT(DATETIME,
'30/04/2001', 103))
GROUP BY q.Ref_O) Fac ON
q.Ref_O = Fac.Ref_O LEFT OUTER JOIN
(SELECT q.Ref_O, SUM(P.ImportePedido * 166.386)
AS PtasMateriales
FROM (SELECT O.Ref_OrFa, O.Descripcion, O.Ptas_P, C.Empresa,
O.Ref_O, O.Día_Entrega, O.Situación_O, O.Día_Apertura
FROM dbo.Ofertas O INNER JOIN
dbo.Clientes C ON O.IdCliente = C.IdCliente
WHERE (O.Situación_O = 'PED' OR
O.Situación_O = 'GAR' OR
O.Situación_O = 'ENT') AND
(O.Día_Entrega > CONVERT(DATETIME, @F_Inicio, 103) OR
O.Día_Entrega IS NULL) AND
(O.Día_Apertura < CONVERT(DATETIME, @F_Fin, 103) OR
O.Día_Apertura IS NULL)) q INNER JOIN
dbo.PEDIDOS P ON q.Ref_O = P.Ref_O
WHERE (P.F_Factura < CONVERT(DATETIME, @F_Fin, 103)) AND
(P.Facturado = 1)
GROUP BY q.Ref_O) Mat ON
q.Ref_O = Mat.Ref_O LEFT OUTER JOIN
(SELECT q.Ref_O, SUM(h.Horas) AS H_R,
AVG(GFH.Precio_hora_General) AS VMHR
FROM dbo.qryOFsEntPedGar q INNER JOIN
dbo.Horas h ON q.Ref_O = h.Ref_O INNER JOIN
dbo.Tarjetas t ON h.IdTarjeta = t.IdTarjetaTiempo INNER JOIN
dbo.GFH ON h.GFH = dbo.GFH.GFH
WHERE (t.FechaEntrada < CONVERT(DATETIME, @F_Fin, 103))
GROUP BY q.Ref_O) HR ON q.Ref_O = HR.Ref_O
Le he estado echando un vistazo, y por lo que veo, no hay otra solución con las tablas normalizadas.
En estos casos, si te baja demasiado el rendimiento, debes denormalizar un poco y poner acumulados que te eviten ir a otras tablas. Con la consiguiente complejidad de actualización y proceso de recalculo de dichos campos (para dejarlo bien del todo).
Hay casos en los que es interesante denormalizar. Sobre el tema hay un artículo muy interesante en la web de Fernando G. Guerrero (no recuerdo el nombre), a ella puedes llegar desde la mía, yendo a la sección BackOffice > SQL Server > Webs amigas.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas