Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 19-10-2008
Angel Fernández Angel Fernández is offline
Miembro
 
Registrado: may 2004
Ubicación: Valencia - España
Posts: 141
Poder: 20
Angel Fernández Va por buen camino
Saber número de registros distintos en una columna de una consulta.

Saludos al foro.

Quisiera saber el número de registros distintos para una columna obtenida a través de una consulta.

Me explicaré:

Tengo una consulta realizada sobre una BD de firebird 2.0. La consulta la realizo con el componente fibdataset de los fibplus mediante una sentencia sql parecida a esto:

Código SQL [-]
select fecha, hora, sensor, dato
from tablasensores
where fecha between fecha1 and fecha2

Esto me devuelve una cantidad de datos de sensores, por ejemplo, s1, s2, s3, etc.

Pero por ejemplo, puede ser que el sensor s4 no tenga datos recogidos entre la fecha1 y la fecha2. Quiero saber qué sensores son los que tienen datos.
Esto es fácil de obtener mediante una consulta sql tal que:

Código SQL [-]
select distinct sensor
from tablasensores
where fecha between fecha1 and fecha2

El problema es que tanto la primera consulta como la segunda son bastante lentas (entre 1 y 2 minutos) porque la BD tiene millones de datos. La primera consulta no puedo dejar de hacerla (me devuelve una serie de datos con los que hago un gráfico y demás), pero la segunda es la que estoy tratando de no hacerla, es decir, de hacer algo más rápido.

Que yo sepa, la propiedad filter no acepta la clausula 'distinct' (lo he probado y no), por lo que, pregunta 1: ¿Se puede hacer de alguna otra forma mediante filtros?

Otra posibilidad sería hacer la consulta 2 sobre los resultados arrojados por la consulta 1 que son unos cuantos miles. Pregunta 2: ¿Se puede hacer esto?

Resumiendo y sintetizando:

1: ¿Se puede obtener lo que hace la clausula 'distinct' mediante filtros?

2: Si lo anterior no se puede: ¿se puede hacer una consulta sobre los resultados de otra consulta (y cómo hacerlo)?

Utilizo D7, FireBird 2.0, componentes fibplus, windows xp sp2.

Gracias por adelantado.
Responder Con Cita
  #2  
Antiguo 19-10-2008
Avatar de enecumene
[enecumene] enecumene is offline
Miembro de Oro
 
Registrado: may 2006
Ubicación: Santo Domingo, Rep. Dom.
Posts: 3.040
Poder: 21
enecumene Va por buen camino
Hola, te aconsejo utilizar procedimientos almacenados para ese tipo de consultas ya que tienes millones de datos (cosa que dudo ) y así optimizas la velocidad.

Saludos.
__________________

Mi BLOG - ¡Joder, leanse la guia de estilo!
Las Palabras son enanas, los ejemplos gigantes.
Responder Con Cita
  #3  
Antiguo 19-10-2008
Angel Fernández Angel Fernández is offline
Miembro
 
Registrado: may 2004
Ubicación: Valencia - España
Posts: 141
Poder: 20
Angel Fernández Va por buen camino
Gracias enucemene.

Sin embargo, uf, procedimientos almacenados... ¿podías darme algún ejemplo? es que esto de los sp no lo llevo muy bien.

¿Por qué dudas de que la BD tenga millones de datos? Ahora mismo tengo 12.000.000 (aprox.) datos en la base. Doce millones y pico de datos. Te lo aseguro.
Responder Con Cita
  #4  
Antiguo 19-10-2008
Avatar de enecumene
[enecumene] enecumene is offline
Miembro de Oro
 
Registrado: may 2006
Ubicación: Santo Domingo, Rep. Dom.
Posts: 3.040
Poder: 21
enecumene Va por buen camino
Hola, Aquí te dejo un pequeño manual de procedimientos almacenados válido también para Firebird:

http://www.firebird.com.mx/imagenes/...lmacenados.pdf

Saludos
__________________

Mi BLOG - ¡Joder, leanse la guia de estilo!
Las Palabras son enanas, los ejemplos gigantes.
Responder Con Cita
  #5  
Antiguo 19-10-2008
lbuelvas lbuelvas is offline
Miembro
 
Registrado: may 2003
Ubicación: Colombia
Posts: 377
Poder: 21
lbuelvas Va por buen camino
Un procedimiento almacenado creo que no soluciona tu problema.

Es posible, sin embargo, que tus consultas puedan mejorar si incorporas un indice sobre el campo fecha (en caso que no lo tengas).

Aunque puede definir una estrategia valida (a pesar de tener redundancia de datos) que consistiria en elaborar un trigger after insert (despues de insertar) sobre la tabla tablasensores que escriba a otra tabla llamada por ejemplo fechassensores, los campo de esta tabla pueden ser {fecha, sensor, contador}.

Entonces cada vez que ingrese un registro a la tabla tablasensores, busque en la tabla fechassensores si existe un registro con la fecha y numero de sensor, en caso de no existir crea el registro con los valores {fecha, sensor, 1}; en caso que ya exista un registro, simplemente le sumas uno al campo contador.

Defini el campo contador por si necesitas saber cuantas registros por fecha hay para cada sensor.
__________________
Luis Fernando Buelvas T.
Responder Con Cita
  #6  
Antiguo 19-10-2008
lbuelvas lbuelvas is offline
Miembro
 
Registrado: may 2003
Ubicación: Colombia
Posts: 377
Poder: 21
lbuelvas Va por buen camino
Olvidaba comentar que luego hacer consultas en la fechassensores va a ser relativamente facil y por supuesto muchisimo mas rapido.

Logicamente el sacrificio que tendra el sistema es que sera mas lento la entrada debido a las verificaciones, faltaria saber que tan alto es el volumen de registros por unidad de tiempo (por ejemplo cuantos registros po minuto) entran a la base de datosa ver si esta estrategia pueda trabajar de manera eficiente.
__________________
Luis Fernando Buelvas T.
Responder Con Cita
  #7  
Antiguo 19-10-2008
Angel Fernández Angel Fernández is offline
Miembro
 
Registrado: may 2004
Ubicación: Valencia - España
Posts: 141
Poder: 20
Angel Fernández Va por buen camino
Gracias por vuestra ayuda y comentarios.

Lo que comentas, Luis, me parece muy interesante, una buena idea. Sin embargo, con una base de datos ya implementada y en uso desde hace meses, en la que ya hay doce millones y pico de registros, me parece que ya es un poco tarde porque me obliga a reingresar todos los datos.

Es desde luego buena idea para llevarla a cabo con la base en blanco. Tomo nota para una futura base de datos.

Deduzco, por lo que me comentáis, que no se puede ni filtrar los datos, ni hacer una consulta sobre los resultados de otra consulta que eran las dos opciones que lanzé al principio. ¿Es esto correcto?

De ser así, y en este punto en el que ya tengo ese montón de datos, ¿qué me queda? Lanzar la segunda consulta que apuntaba en mi primera intervención y esperar ¿no?

Lo que me preguntas Luis, en la BD ingresa un dato cada minuto de un total de 62 sensores, de ahí la cantidad inmensa de datos a la que no daba crédito enecumene. Y esa cantidad es para medio año: aún nos queda ingresar el otro medio.

Debo decir, que a pesar de esa monstruosidad, Firebird la mueve con soltura y en ningún momento se nota ese peso. Detrás hay un buen trabajo en cuanto a índices, que me llevó bastante tiempo y muchas consultas a este foro. Si os interesa, podéis echar un ojo a este hilo:

http://www.clubdelphi.com/foros/showthread.php?t=53508

Gracias.

Un saludo.
Responder Con Cita
  #8  
Antiguo 20-10-2008
lbuelvas lbuelvas is offline
Miembro
 
Registrado: may 2003
Ubicación: Colombia
Posts: 377
Poder: 21
lbuelvas Va por buen camino
Bueno lo que planteas es un sistema en linea que recibe registros de 62 sensores donde cada uno envia informacion cada minuto.

En esas condiciones no tendrias problema con la solucion que te planteo, en ocasiones es bueno tener tablas resumen para evitar tareas que consumen demasiado tiempo al motor de bases de datos en dar respuesta.

Lo que puedes haceren realizar pruebas en una base de datos en blanco como lo estás comentando, cuando te funcionen implementas los triggers en tu base de datos en producción.

Para los datos antiguos, debes elaborar un procedimiento almacenado que reconstruya los registros de fechas que ya estén registradas en la base de datos.

La ejecución de ese procedimiento almacenado no te va a interferir con el trabajo de los triggers con los datos nuevos.
__________________
Luis Fernando Buelvas T.
Responder Con Cita
  #9  
Antiguo 20-10-2008
lbuelvas lbuelvas is offline
Miembro
 
Registrado: may 2003
Ubicación: Colombia
Posts: 377
Poder: 21
lbuelvas Va por buen camino
Si colocas los metadatos de las tablas sobre las cuales necesitas la elaboración de los triggers y procedimientos almacenados, con mucho gusto puedo colaborarte y de paso te introduces en el manejo de procedimientos almacenados.
__________________
Luis Fernando Buelvas T.
Responder Con Cita
  #10  
Antiguo 20-10-2008
Avatar de RONPABLO
[RONPABLO] RONPABLO is offline
Miembro Premium
 
Registrado: oct 2004
Posts: 1.514
Poder: 21
RONPABLO Va por buen camino
Con respecto a los indices que te sugirieron los has puesto?? ya los tiene la base de datos?? una consulta en una tabla con indices y sin indices es realmente diferente y puede ser una solución muy buena
__________________
"Como pasa el tiempo..... ayer se escribe sin H y hoy con H"
Responder Con Cita
  #11  
Antiguo 20-10-2008
Angel Fernández Angel Fernández is offline
Miembro
 
Registrado: may 2004
Ubicación: Valencia - España
Posts: 141
Poder: 20
Angel Fernández Va por buen camino
Muchas gracias Luis por tu ofrecimiento, muy amable. Lo que ocurre es que la tabla es propiedad de mi cliente que, aunque aún no me ha pagado, no estoy seguro de que le gustara la idea.

Puedo explicar un poco de qué va: Dado que se recoge un dato cada minuto esto supone una cantidad inmensa de datos. Se estudiaron varias posibilidades, tomar la media cada 5 minutos, cada 10, etc. pero al final se decidió tomar todos los datos y si luego sobraban mejor que si faltaban.

He creado unos índices para luego agrupar los datos cada hora por ejemplo. La tabla tiene una columna que le llamo HORA_INT y que convierte la fecha y hora en un formato integer tal que así:

Fecha: 01/01/2008 Hora: Entre 10:00 y 10:59 --> Columna HORA_INT= 2008010110
Fecha: 01/01/2008 Hora: Entre 11:00 y 11:59 --> Columna HORA_INT= 2008010111
etc.

Esta columna tiene un índice.

Con un campo calculado obtengo un dato "Rango de tiempo" que por ejemplo, HORA_INT=2008010110 lo convertiría en "De 10:00 a 10:59"
Con un proceso similar, tengo varios índices: DIA_INT, SEMANA_INT, 5MINUTOS_INT, ETC. Así, si quiero un dato cada día por ejemplo, agrupo los datos por días obteniendo la media, el máximo y el mínimo.

Fecha Rango de Tiempo Sensor Media Máximo Mínimo
-------------------------------------------------------------
01/01/2008 De 10:00 a 10:59 01 15.00 16.00 14.00
01/01/2008 De 11:00 a 11:59 01 16.00 16.00 14.00
01/01/2008 De 12:00 a 12:59 01 17.00 16.00 14.00
01/01/2008 De 13:00 a 13:59 01 18.00 16.00 14.00

etc.


Con estos índices obtengo algo que yo entiendo como "razonablemente rápido". Una consulta en un rango de fechas de 3 meses, para 31 sensores, agrupados por hora, tarda algo menos de 2 minutos y devuelve 40.000 registros con los que elaboro un gráfico. Mi ordenador es un amd a 3000, mononúcleo con 2,5 GB de ram con win xp sp2.

Para elaborar el gráfico me iría bien saber qué sensores no tienen ningún dato en el rango de fechas de la consulta.

En fín, espero haberme expresado bien.

Un saludo.
Responder Con Cita
  #12  
Antiguo 21-10-2008
Avatar de RONPABLO
[RONPABLO] RONPABLO is offline
Miembro Premium
 
Registrado: oct 2004
Posts: 1.514
Poder: 21
RONPABLO Va por buen camino
Con que componentes trabajas??? es que 2 ó 3 minutos en una consulta es un tiempo muy largo..... yo por ejemplo he llegado a tener (y se que no es tan alto como el volumen que maneja) clientes con tablas que superan los 2 millones y los resultados de velocidad son similares a cuando hay pocos datos...
__________________
"Como pasa el tiempo..... ayer se escribe sin H y hoy con H"
Responder Con Cita
  #13  
Antiguo 21-10-2008
Angel Fernández Angel Fernández is offline
Miembro
 
Registrado: may 2004
Ubicación: Valencia - España
Posts: 141
Poder: 20
Angel Fernández Va por buen camino
Cita:
Empezado por RONPABLO Ver Mensaje
Con que componentes trabajas??? es que 2 ó 3 minutos en una consulta es un tiempo muy largo..... yo por ejemplo he llegado a tener (y se que no es tan alto como el volumen que maneja) clientes con tablas que superan los 2 millones y los resultados de velocidad son similares a cuando hay pocos datos...
Utilizo los componentes FIBPLUS. La consulta la lanzo desde desde un FIBDATASET. Realmente, lo que más tiempo lleva es cuando hay que agrupar por hora, día, etc y tiene que calcular medias, máximos y mínimos.

¿Qué componentes utilizas tú? Desde luego estoy muy interesado en la velocidad.
Responder Con Cita
  #14  
Antiguo 21-10-2008
Avatar de RONPABLO
[RONPABLO] RONPABLO is offline
Miembro Premium
 
Registrado: oct 2004
Posts: 1.514
Poder: 21
RONPABLO Va por buen camino
Pues yo utilizó unos que deben de correr más lento que los tuyos... los MDOLib ya que tiene mucho tiempo sin actualizar....

Descarga algún programa para analizar las consultas y mira que te dice, si de verdad está usando los indices que quieres... Yo uso uno llamado DataBase WorkBench, tiene una versión trial, con ella podrás mirar los análisis de las consultas.... y hay otros que te pueden servir...
__________________
"Como pasa el tiempo..... ayer se escribe sin H y hoy con H"
Responder Con Cita
  #15  
Antiguo 25-10-2008
Avatar de boreg
boreg boreg is offline
Miembro
 
Registrado: oct 2007
Ubicación: México, México
Posts: 76
Poder: 17
boreg Va por buen camino
Cita:
Empezado por Angel Fernández Ver Mensaje
...Para elaborar el gráfico me iría bien saber qué sensores no tienen ningún dato en el rango de fechas de la consulta....
Quizás para ese resultado te vendría bien una consulta con EXISTS:

Código SQL [-]
Select *
from CatSensores CS
where not exists(
select *
from tablasensores TS
where TS.IDSENSOR = CS.IDSENSOR
and fecha between fecha1 and fecha2)

tambien opino que podrías utilizar una tabla "temporal" para vaciar los resultados de tu primer consulta y trabajar con esos datos.

Espero que en algo te sea de ayuda. Saludos
Responder Con Cita
  #16  
Antiguo 25-10-2008
Angel Fernández Angel Fernández is offline
Miembro
 
Registrado: may 2004
Ubicación: Valencia - España
Posts: 141
Poder: 20
Angel Fernández Va por buen camino
Gracias boreg por tu ayuda.

Sin embargo, el problema es que lanzar una segunda consulta haría lento el proceso (la primera consulta tarda entre 1 y 2 minutos).

Y lo de la tabla temporal tendría que recorrer todos los datos y también sería lento (en ocasiones, la consulta me devuelve varias decenas de miles de resultados).

En realidad lo de la tabla temporal es algo que me llama la atención desde hace tiempo pero que no llego a utilizar bien del todo. A veces he usado la memorytable de las rxlib pero es muy lento porque hay que recorrer todos los datos de la consulta, no acepta un dataset como origen de datos.
¿Hay algún componente de tabla temporal que recoga los resultados de un dataset?

Un saludo.
Responder Con Cita
  #17  
Antiguo 03-11-2008
Avatar de rastafarey
rastafarey rastafarey is offline
Miembro
 
Registrado: nov 2003
Posts: 927
Poder: 21
rastafarey Va por buen camino
Resp

Código SQL [-]
select first 1 fecha, hora, dato
from tablasensores
where fecha between fecha1 and fecha2 and sensor = 1
union
select first 1 fecha, hora, dato
from tablasensores
where fecha between fecha1 and fecha2 and sensor = 2
union
select first 1 fecha, hora, dato
from tablasensores
where fecha between fecha1 and fecha2 and sensor = 3

Pruba con algo asi. Y sando case o luego lansas la consulta sobre esta misma conculta o usando with.

No tomen esta consulta a ala ligera hay varias consultas. pero se esta usando first 1 Aqui hay muchos beneficios.
__________________
Todo se puede, que no exista la tecnología aun, es otra cosa.
Responder Con Cita
  #18  
Antiguo 06-11-2008
Angel Fernández Angel Fernández is offline
Miembro
 
Registrado: may 2004
Ubicación: Valencia - España
Posts: 141
Poder: 20
Angel Fernández Va por buen camino
Gracias rastafarey.

Tu código tiene buena pinta. Ya lo pruebo a ver qué tal.

Un saludo.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
como saber numero de registros de una tabla usando un clientdataset? acl_gandalf Conexión con bases de datos 11 26-06-2023 20:09:19
Saber el número de registros llenos en un campo mmmbopzombie Tablas planas 2 28-11-2005 10:54:31
Query, como saber el numero de Registros ? Pascual Montes Conexión con bases de datos 5 09-12-2004 18:14:17
Saber cuantos registros origino la consulta JorgeBec SQL 1 12-11-2004 17:48:17
Saber el numero de registros consultados estudiante SQL 2 13-05-2003 01:12:09


La franja horaria es GMT +2. Ahora son las 22:31:28.


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
Copyright 1996-2007 Club Delphi