Ir al contenido


Foto

Problema con una consulta SQL en Firebird 2.5


  • Por favor identifícate para responder
5 respuestas en este tema

#1 AngelF

AngelF

    Advanced Member

  • Miembros
  • PipPipPip
  • 100 mensajes
  • LocationValencia - España

Escrito 21 noviembre 2012 - 01:24

Hola compañeros:

Tengo un problema con una consulta en Firebird 2.5 que no sé solucionar ni por qué ocurre. A ver si alguien puede ver más allá.

El caso es que tengo 2 tablas, una que acumula datos de unos sensores de humedad y temperatura (tabla HUM_TEM) y otra donde guardo los sensores (tabla SENSORES). En la tabla HUM_TEM se almacenan los datos de cada sensor y la fecha en que se recogió, entre otros. Estos son los campos:
IDDATO - id del dato
IDSENSOR - conecta con la tabla sensores, formato 1,2, etc
FECHA - fecha en formato 01/03/2001
HORA  - hora en formato 12:05
DIA_INT - fecha en formato 20010301 (para el día 01/03/2001)
DATO    - dato del sensor en formato 56,25
CORRECTO  - si/no
AAA - año en formato 2001
MMM - mes en formato 1,..12
DDD - día del año en formato 1...366
SEM - semana del año en formato 1..52
HHH - hora en formato 0...23
MNT - minuto en formato 0..59
DSM - dia de la semana en formato 1 ..7

Campos de la tabla SENSORES:
IDSENSOR -id del sensor
REF  - nombre corto del sensor, 'HUM001'
UBICACION - campo texto
NOMBRE    - campo texto, nombre largo "Sensor de humedad 1"
COMENTARIO - campo texto
ACTIVO    - si/no
BUENAFUNCION -si/no

Bien. Ahora lanzo la siguiente consulta:

SELECT
HUM_TEM.HHH, avg(hum_tem.dato) as MEDIA, sensores.ref as Sensor
FROM hum_tem, sensores
WHERE sensores.idproyecto =  1
AND HUM_TEM.dia_int BETWEEN 20100101 AND 20100331
AND HUM_TEM.DSM = 1
AND SENSORES.REF IN ('HUM001','HUM002','HUM003', 'TEM001', 'TEM002','TEM003')
AND sensores.idsensor = hum_tem.idsensor
AND HUM_TEM.DATO IS NOT NULL
group by HHH, ref
order by HHH, ref


Con esta consulta lo que quiero es obtener los promedio por hora, entre las fechas 01/01/2010 y 31/03/2010, de los sensores indicados en 'HUM001','HUM002','HUM003', 'TEM001', 'TEM002','TEM003' PERO sólo los que el día de la semana es igual a domingo ('AND HUM_TEM.DSM = 1 ')

La consulta se realiza bien, sin problemas, pero hace caso omiso de la instrucción:
AND HUM_TEM.DSM = 1
Y me devuelve los mismos datos que si omito esta línea.

Si incluyo el campo DSM en los campos obtenidos, sí que me hace caso de la instrucción filtro por domingo, pero tengo entonces que incluir el campo DSM en el GROUP BY y obtengo un resultado no deseado.
Probando, he comprobado que sí me acepta otros filtros, como por ejemplo si pongo
AND HUM_TEM.Hora BETWEEN '12:00:00' AND '23:59:00'
sí que me realiza bien el filtro.

¿Por qué entonces no me acepta filtrar por el campo DSM?

El campo DSM tiene un índice, al igual que el campo HORA.

Uso Delphi 7, FB 2.5 y Windows Vista 64 bits. ¿Alguna ayuda?

Un saludo.



  • 0

#2 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 21 noviembre 2012 - 01:32

Sugerencia que probablemente te pueda ayudar:

Encierra tus condiciones (sobre todo de fecha) entre paréntesis... A mi en lo personal me ha dado algunos problemillas este detalle y podría ser este el caso porque no le veo nada que pudiera estar generando el problema...

Saludox ! :)

P.D. Porqué no usar JOIN para el enlace de tus tablas ??? Algo así :


SELECT
HUM_TEM.HHH, avg(hum_tem.dato) AS MEDIA, sensores.REF AS Sensor
FROM hum_tem
LEFT JOIN sensores ON sensores.idsensor = hum_tem.idsensor
WHERE (sensores.idproyecto =  1)
AND (HUM_TEM.dia_int BETWEEN 20100101 AND 20100331)
AND (HUM_TEM.DSM = 1)
AND (SENSORES.REF IN ('HUM001','HUM002','HUM003', 'TEM001', 'TEM002','TEM003'))
AND (HUM_TEM.DATO IS NOT NULL)
GROUP BY HHH, REF
ORDER BY HHH, REF



  • 0

#3 AngelF

AngelF

    Advanced Member

  • Miembros
  • PipPipPip
  • 100 mensajes
  • LocationValencia - España

Escrito 21 noviembre 2012 - 01:38

Gracias Fenareth, por tu rápida respuesta (caramba, casi instantánea).

Fijándome bien me he dado cuenta que quizá sí que influya. Lo que pasa es que me devuelve el mismo número de resultados, pero no los mismos.
Quizá no me he fijado bien.
Lo estudio más despacio y digo algo.

Y otra cosa que me comentas: ¿no es lo mismo el JOIN que mi instrucción? ¿Quizá más rápido JOIN?

Un saludo.
  • 0

#4 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 21 noviembre 2012 - 03:18

Bueno aunque el producto cartesiano de las tablas puede generarte el resultado que esperas, utilizar JOIN es bastante más eficiente para el motor de la base de datos, además de que puedes usar sus variantes: INNER JOIN, LEFT JOIN, RIGHT JOIN, etc. , según te sea necesario...

Saludox ! :)
  • 0

#5 AngelF

AngelF

    Advanced Member

  • Miembros
  • PipPipPip
  • 100 mensajes
  • LocationValencia - España

Escrito 21 noviembre 2012 - 03:44

Efectivamente, sí que influía.

Lo que pasó es que me fijaba sólo en el número de datos devueltos y como la consulta lo que hace es "agrupar" por hora y sensor, me daba siempre el mismo número de resultados que era 24 (horas, de 0 a 23) x Nº de sensores seleccionado. Y yo obcecado, pensaba que era el mismo resultado.

Al confirmarme Fenareth que no veía nada raro, ya me mosqueé y lo miré bien.

¡Gracias! Otro éxito del foro Delphiaccess.
  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 28 noviembre 2012 - 08:24

Hola,
Se bien que esto está por resuelto, pero quisiera preguntarte (de curioso nomás) si te es tan necesario haber desnormalizado la fecha y hora en campos numéricos. Muchos de los campos que colocas se pueden "reconstruir" o calcular en función de otros, por ejemplo SEM, DSM y DDD se pueden obtender de forma casi directa desde un campo fecha/hora sin mucho problemas.

¿Son demasiados registros? Como para que el llevar esta desnormalización se facilite la incorporación de índices sobre estos campos y tener más flexibilidad en aprovechar diversos índices.
Porque de ser asi yo en todo caso dispondría únicamente de los campos DD, MM, AAAA para almacenar el número del día, el mes y el año. El resto, si se necesita, sólo se obtiene por cálculos y a efectos de presentación se "compone" la fecha aprovechando por ejemplo las funciones Encode/Decode. Lo mismo para las horas: HH, MM, SS, MS (si es necesario esta escala y precisión).

Saludos,
  • 0




IP.Board spam blocked by CleanTalk.