Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Ayuda con consulta (https://www.clubdelphi.com/foros/showthread.php?t=80249)

Salnhack 12-09-2012 21:45:20

Ayuda con consulta
 
Hola a todos
escribo para ver quien me puede ayudar

tengo 4 tablas

carro
idcarro nocarro indicecons
1 TSA-590 10
2 TSA-250 20

hojaruta
idhojaruta idcarro nohojatuta chofer
1 1 150 Juan
2 2 151 Pedro

deschojaruta
iddeschojaruta idhojaruta origen destino kmrecorrido fecha
1 1 Las Tunas Holguin 74 1/09/2012
2 1 Holguin Las Tunas 74 1/09/2012
3 2 Las Tunas Santuago 204 2/09/2012

consumo
idconsumo idcarro consumo chip fecha
1 1 10 150 1/09/2012
2 2 50 12 1/09/2012
3 1 10 20 2/09/2012
4 2 10 25 2/09/2012
5 2 40 50 3/09/2012


necesito hacer una consulta que me selecione por carro los km recorrido y el consumo en un rango de fecha 1/9/2012-30/9/2012
algo asi

carro indicecons kmrecorrido consumo

TSA-590 10 148 20

TSA-250 20 204 100
este es el resultado que me deveria dar

y estoy utilizando esta consulta
Código Delphi [-]
     SQL.Add('Select SUM(deschojaruta.kmrecorrido),SUM(consumo.consumo), carro.nocarro, carro.indicecons from deschojaruta,carro, hojaruta, consumo');
     SQl.Add('Where deschojaruta.fecha between :binicio and :bfin and deschojaruta.idhojaruta=hojaruta.idhojaruta and hojaruta.idcarro=carro.idcarro and consumo.fecha between :binicio and :bfin and carro.idcarro=consumo.idcarro');
     SQL.Add('Group By carro.nocarro, carro.indicecons');
     SQL.Add('Order By carro.nocarro');
pero me devuelve los resultados incorrectamente

duilioisola 12-09-2012 23:31:20

He traducido tu SQL utilizando JOINs.
Código SQL [-]
Select SUM(dhr.kmrecorrido), SUM(co.consumo), c.nocarro, c.indicecons 
from carro c
join consumo co
on c.idcarro=co.idcarro
join hojaruta hr
on c.idcarro=hr.idcarro
join deschojaruta dhr
on dhr.idhojaruta=hr.idhojaruta
Where 
co.fecha between :binicio and :bfin and
dhr.fecha between :binicio and :bfin
Group By c.nocarro, c.indicecons
Order By c.nocarro
El probelma, me parece, radica en que no tienes unido de ninguna manera el consumo con hojaruta.
En este caso, el SELECT te devolverá todos los elementos de consumo y todos los elementos de hojaruta y todas sus posibles combinaciones.

Si luego de filtrar entre fechas obtienes:
consumo (1, 2, 3)
hojaruta (a, b, c)
El select te devolverá:
(1-a, 1-b, 1-c, 2-a, 2-b, 2-c, 3-1, 3-b, 3-c)

Supongo que la mejor opción, puesto que no hay relación entre consumo y hojaruta es hacer dos SELECTs dentro de uno:

Algo así:
Código SQL [-]
Select c.nocarro, c.indicecons,
(
select SUM(dhr.kmrecorrido) from hojaruta hr
on c.idcarro=hr.idcarro
join deschojaruta dhr
on dhr.idhojaruta=hr.idhojaruta
dhr.fecha between :binicio and :bfin
) as kmrecorrido,
(
select SUM(co.consumo) from consumo co
on c.idcarro=co.idcarro
co.fecha between :binicio and :bfin and
) as consumo
from carro c
Order By c.nocarro

Salnhack 13-09-2012 00:42:18

hola duilioisola
he probado el codigo que me sugeriste pero me da error en sintaxis

hoyosfelix 13-09-2012 18:07:06

Respuesta "Ayuda con consulta"
 
Buen día Salnhack, te paso un select para probar

SELECT C.IDCARRO, C.NOCARRO, C.INDICECONS, SUM(DHR.KMRECORRIDO), SUM(CO.CONSUMO)
FROM CARRO C INNER JOIN HOJARUTA HR ON HR.IDCARRO = C.IDCARRO
INNER JOIN DESCHOJARUTA DHR ON DHR.IDHOJARUTA = HR.IDHOJARUTA
INNER JOIN CONSUMO CO ON CO.IDCARRO = C.IDCARRO
WHERE CO.FECHA BETWEEN :FECHA1 AND :FECHA2
GROUP BY C.IDCARRO, C.NOCARRO, C.INDICECONS
ORDER BY C.IDCARRO


Saludos...

Casimiro Notevi 13-09-2012 18:41:10

Cita:

Empezado por hoyosfelix (Mensaje 443017)
...

Recuerda poner los tags al código fuente, ejemplo:



Y te ahorras todo el trabajo que has hecho poniendo colores por palabras, tipos de letras, etc.

Gracias :)

hoyosfelix 13-09-2012 18:51:21

Respuesta "Ayuda con consulta"
 
Buena tarde,
Gracias por el consejo.
Realmente, intenté resaltar la sintaxis de SQL, pero no entendía muy bien cómo funcionaba, ahora me quedó claro.
En la próxima entrada voy a utilizar correctamente los tag's.
Saludos.

Casimiro Notevi 13-09-2012 18:54:45

Gracias ^\||/

Salnhack 13-09-2012 21:08:24

Cita:

Empezado por hoyosfelix (Mensaje 443017)
Buen día Salnhack, te paso un select para probar

SELECT C.IDCARRO, C.NOCARRO, C.INDICECONS, SUM(DHR.KMRECORRIDO), SUM(CO.CONSUMO)
FROM CARRO C INNER JOIN HOJARUTA HR ON HR.IDCARRO = C.IDCARRO
INNER JOIN DESCHOJARUTA DHR ON DHR.IDHOJARUTA = HR.IDHOJARUTA
INNER JOIN CONSUMO CO ON CO.IDCARRO = C.IDCARRO
WHERE CO.FECHA BETWEEN :FECHA1 AND :FECHA2
GROUP BY C.IDCARRO, C.NOCARRO, C.INDICECONS
ORDER BY C.IDCARRO


Saludos...

Hola hoyofelix he probado tu codigo pero me da error en sintaxis falta operador
tengo poco conocimiento de SQL solo lo basico por eso me resulta dificil lograr el resultado que espero

Casimiro Notevi 13-09-2012 21:22:37

Cita:

Empezado por Salnhack (Mensaje 443043)
Hola hoyofelix he probado tu codigo pero me da error en sintaxis falta operador
tengo poco conocimiento de SQL solo lo basico por eso me resulta dificil lograr el resultado que espero

Ayuda a que te ayudemos ;)
Se parará en una línea, indicará algo más, el mensaje completo y exacto dirá otra cosa, pégalo aquí... no somos adivinos ;)

hoyosfelix 13-09-2012 21:58:54

Respuesta "Ayuda con consulta"
 
Hola,
Para verificar que la consulta traiga algún resultado se debe probar primero en una herramienta de SQL, por ejemplo el FlameRobin.
Allí en vez de :fecha1 y :fecha2 podés cambiar por un rango que tengas en tu tabla consumo, ejemplo:

Código SQL [-]
SELECT C.IDCARRO, C.NOCARRO, C.INDICECONS, SUM(DHR.KMRECORRIDO), SUM(CO.CONSUMO) 
FROM CARRO C 
INNER JOIN HOJARUTA HR ON HR.IDCARRO = C.IDCARRO   
INNER JOIN DESCHOJARUTA DHR ON DHR.IDHOJARUTA = HR.IDHOJARUTA   
INNER JOIN CONSUMO CO ON CO.IDCARRO = C.IDCARRO 
WHERE CO.FECHA BETWEEN '2012-09-01' AND '2012-09-30' 
GROUP BY C.IDCARRO, C.NOCARRO, C.INDICECONS 
ORDER BY C.IDCARRO

Si devuelve un resultado significa que la consulta está correcta y luego ya se puede pasar al SQL de tu componente Query en Delphi.
Es cierto lo que dice Casimiro Notevi, sería interesante saber en dónde estás corriendo la consulta, si en Delphi, en FlameRobin u otro; si tuvieramos más datos podríamos ir directo al problema.

Saludos.

Salnhack 13-09-2012 22:08:08

1 Archivos Adjunto(s)
La consulta la estoy corriendo en deplhi y el error que me muestra es el que adjunto

Casimiro Notevi 13-09-2012 22:30:37

Parece que no has tecleado bien la consulta, ¿puede ser?, pon el código que lo veamos.
Seguimos sin ser adivinos ;)

Salnhack 13-09-2012 22:46:42

este es el codigo completo que le paso al query

Código Delphi [-]
   with datamodule29.Query2 do
    Begin
     Close;
     SQl.Clear;
     SQL.Add('Select idmes from mes where mes=:pmes');
     ParamByName('pmes').AsString:=suiDBLookupComboBox2.Text;
     Open;
     mes:=FieldByName('idmes').AsInteger;
     Close;
     SQl.Clear;
     SQL.Add('Select * from mes where idmes=:pidmes');
     ParamByName('pidmes').AsInteger:=mes;
     Open;
     inicio:=FieldByName('inicio').AsString;
     fin:=FieldByName('fin').AsString;
     Close;
     SQL.Clear;
     SQL.Add('SELECT C.IDCARRO, C.NOCARRO, C.INDICECONS, SUM(DHR.KMRECORRIDO), SUM(CO.CONSUMO)');
     SQL.Add('FROM CARRO C INNER JOIN HOJARUTA HR ON HR.IDCARRO = C.IDCARRO');
     SQL.Add('INNER JOIN DESCHOJARUTA DHR ON DHR.IDHOJARUTA = HR.IDHOJARUTA');
     SQl.Add('INNER JOIN CONSUMO CO ON CO.IDCARRO = C.IDCARRO');
     SQL.Add('WHERE CO.FECHA BETWEEN :FECHA1 AND :FECHA2');
     SQL.Add('GROUP BY C.IDCARRO, C.NOCARRO, C.INDICECONS');
     SQL.Add('ORDER BY C.IDCARRO');
     ParamByName('FECHA1').AsString:=inicio;
     ParamByName('FECHA2').AsString:=fin;
     Open;
    end;

hoyosfelix 13-09-2012 23:03:50

Respuesta "Ayuda con consulta"
 
Hola, prueba de esta manera:

Código Delphi [-]
var    
vsql : string;  

begin   
  ....   
  vsql := ' SELECT C.IDCARRO, C.NOCARRO, C.INDICECONS, SUM(DHR.KMRECORRIDO), SUM(CO.CONSUMO) ';   
  vsql := vsql + ' FROM CARRO C INNER JOIN HOJARUTA HR ON HR.IDCARRO = C.IDCARRO ';   
  vsql := vsql + ' INNER JOIN DESCHOJARUTA DHR ON DHR.IDHOJARUTA = HR.IDHOJARUTA ';   
  vsql := vsql + ' INNER JOIN CONSUMO CO ON CO.IDCARRO = C.IDCARRO ';    
  vsql := vsql + ' WHERE CO.FECHA BETWEEN :FECHA1 AND :FECHA2 ';   
  vsql := vsql + ' GROUP BY C.IDCARRO, C.NOCARRO, C.INDICECONS ';   
  vsql := vsql + ' ORDER BY C.IDCARRO ';     
  SQL.Add(vsql);    
  ParamByName('FECHA1').AsString:=inicio;   
  ParamByName('FECHA2').AsString:=fin;   
  Open; 
end

Fijate en los espacios al inicio y final de cada vsql, eso te asegura que al concatenar tengas separada tu sql.

Saludos.

Casimiro Notevi 13-09-2012 23:04:14

Ves, así es más fácil, es que no tenemos bola mágica ;)
Código Delphi [-]
SQL.Add('SELECT C.IDCARRO, C.NOCARRO, C.INDICECONS, SUM(DHR.KMRECORRIDO), SUM(CO.CONSUMO)');      
SQL.Add('  FROM CARRO C INNER JOIN HOJARUTA HR ON HR.IDCARRO = C.IDCARRO');      
SQL.Add('  INNER JOIN DESCHOJARUTA DHR ON DHR.IDHOJARUTA = HR.IDHOJARUTA');      
SQL.Add('  INNER JOIN CONSUMO CO ON CO.IDCARRO = C.IDCARRO');      
SQL.Add('  WHERE CO.FECHA BETWEEN :FECHA1 AND :FECHA2');      
SQL.Add('  GROUP BY C.IDCARRO, C.NOCARRO, C.INDICECONS');      
SQL.Add('  ORDER BY C.IDCARRO');

Te falta poner un espacio antes o después, como quieras, en cada línea, para que luego no queden todas "pegadas"

EDITO: Lo que ha dicho hoyosfelix, no lo había visto.

Casimiro Notevi 13-09-2012 23:07:20

hoyosfelix, para que no salga el código "hecho un desastre" te aconsejo que primero envies el mensaje y seguidamente lo edites. El problema es que si le das a "previsualizar" antes de "enviar", se descuadra como te ha salido a ti.

Le tenemos que dar un repaso a la configuración del vbulletin :)

roman 13-09-2012 23:11:14

Cita:

Empezado por Casimiro Notevi (Mensaje 443068)
Te falta poner un espacio antes o después, como quieras, en cada línea, para que luego no queden todas "pegadas"

Eso no es necesario, pues quedan en líneas distintas.

// Saludos

Casimiro Notevi 13-09-2012 23:46:41

Cita:

Empezado por roman (Mensaje 443071)
Eso no es necesario, pues quedan en líneas distintas.
// Saludos

Cierto, solamente hace falta cuando se usa el método escrito por hoyosfelix.
Me he confundido porque yo suelo usar sql.text:
Código Delphi [-]
query.sql.text := 'select *' +
'  from tabla'+
'  where algo';

Salnhack 14-09-2012 15:01:06

Hola a todos he probado la via de hoyosfelix pero me sigue dando el mismo error

Error en sintaxis falta operador

http://clubdelphi.com/foros/attachme...9&d=1347566837

hoyosfelix 14-09-2012 15:47:03

Respuesta "Ayuda con consulta"
 
Buen día, vamos por paso.
1º Quiero saber si la consulta funciona, favor probar en el diseñador de consulta SQL de Access, ejecutarlo y ver resultados.
2º Podriamos ver de nuevo tu sintaxis en Delphi.
3º En tu form poner 2 componentes TDateTimePicker que se llamen fecha1 y fecha2, que vamos a pasar como parámetro a tu consulta.
4º Luego, reemplazar tu código actual por el siguiente, ya que veo en el código anterior que las variables que se pasan a la SQL no son fechas, son enteros pero no fecha de la forma '01/09/2012' y el SQL te lanza el error ya que espera una fecha válida.

Código SQL [-]
var    
  vsql : string;  
begin        
  vsql := ' SELECT C.IDCARRO, C.NOCARRO, C.INDICECONS, SUM(DHR.KMRECORRIDO), SUM(CO.CONSUMO) ';   
  vsql := vsql + ' FROM CARRO C INNER JOIN HOJARUTA HR ON HR.IDCARRO = C.IDCARRO ';   
  vsql := vsql + ' INNER JOIN DESCHOJARUTA DHR ON DHR.IDHOJARUTA = HR.IDHOJARUTA ';   
  vsql := vsql + ' INNER JOIN CONSUMO CO ON CO.IDCARRO = C.IDCARRO ';    
  vsql := vsql + ' WHERE CO.FECHA BETWEEN :FECHA1 AND :FECHA2 ';   
  vsql := vsql + ' GROUP BY C.IDCARRO, C.NOCARRO, C.INDICECONS ';   
  vsql := vsql + ' ORDER BY C.IDCARRO ';     

  SQL.Close;
    SQL.Clear;
    SQL.Add(vsql);    
    Query.Params.Items[0].AsDate:=fecha1.Date;
    Query.Params.Items[1].AsDate:=fecha2.Date;
  SQL.Open; 
end

Saludos.


La franja horaria es GMT +2. Ahora son las 23:02:34.

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