![]() |
mostrar SOLO cliente de los que tengo un sólo registro
Hola,
Estoy trabajando con delphi6 e interbase 7. Tengo que motar un informe (report), y para ello me he creado o lo estoy intentando, un procedimiento que me filtra los cliente por una serie de datos de modo que al final, me muestra todos los registros correspondientes a cada uno de los clientes que cumplen mi condición. Hasta aquí todo bien. El tema es que ahora lo que necesito hacer es que de ese listado que he obtenido, si un cliente tiene más de un registro, entonces NO me muestre los registros de ese alumno y si tiene SÓLO un registro me lo muestre en el listado. Alguna idea????? Por favor, ayuda, Muchas gracias de antemano, y por todo Virginia |
Hola Virginia
No se si te he entendido (podrías poner el SQL que lanzas), pero quizás con un simple Distinct lo puedas solucionar
Espero te sirva |
Hola Cadetill,
por desgracia, no es tan fácil, pues efectivamente utilizo el distint, pero los registros no son totalmente iguales, tienen campos algo distintos. Esto es lo que tengo dentro del bloque del procedimiento:
Muchas gracias, Virginia |
Hola.
Esto te va a listar los registros no repetidos por el campo nombre. select nombre from Tabla EXT where (select count(*) from Tabla INT where INT.nombre = EXT.nombre) = 1 Si esto no es lo que quieres, tendrás que explicarte mejor. Saludos. |
Cita:
Muchas gracias, Virginia |
Hola.
Los problemas de velocidad en una consulta, practicamente siempre se solucionan creando un/varios índice/s adecuado/s. Cuando tienes una subconsulta (como este caso), tienes que prestar especial atención a crear un índice para optimizar esa subconsulta (puesto que se va a lanzar la subconsulta, una vez para cada registro de la consulta principal). Así para una consulta tipo, la comentada : select nombre from Tabla EXT where (select count(*) from Tabla INT where INT.nombre = EXT.nombre) = 1 Solo creando un índice para el campo nombre, vas a aumentar espectacularmente su tiempo de ejecución. NOTA : Este caso es muy simple, en muchos casos vas a necesitar un índice múltiple para optimizar adecuadamente una consulta. Es decir para optimizar una consulta del tipo select .... where Campo1 = X and Campo2 = Y, debes crear un índice compuesto, con los campos Campo1 y Campo2. Saludos. |
Cita:
Saludos. |
Hola,
Cita:
Si, ya sé que el problema lo tengo directamente en la propia consulta, pues como te dije, me tarda horrores directamente desde IB. Lo que quería decir es eso de "y de lanzarla desde delphi, ... ni hablamos..." pues si el problema está el la BD... en Delphi no va a ir bien ni de bromita. En cualquier caso, tendré que revisar los indices que tengo, por que esto mismo me pasó con otra consulta, (creo recordar que tu mismo me dijiste como solucionarlo, esto es, que tuviese especial cuidado con los indices), y esta vez yo creía que los había puesto bien. :o Muchas gracias por la ayuda, Virginia |
Hola a todos,
He estado probando lo que me comentó guillotmarc. El caso es que parece que funcina cuando lo utilizo en un procedimiento que tira de otro procedimiento y de unas tablas, pero me va muy, muy lento. He estado revisando los indices para las tablas que intervienen en cada uno de ellos, parece que tengo todos los campos que se usan en algún momento en el where dentro de un indice directamente en su tabla correspondiente. Pero me sigue llendo lento, muy, muy lento. Arta de no conseguir nada, decidí que tal vez, el hecho de que esté tirando de otro procedimiento, podía ser la causa de la tardanza, (aunque este procedimiento no tarda en ejecutarse), así que decidí montar el procedimiento con todo el código directamente dentro de este procedimiento, para que no dependa de ningún otro. En el otro procedimiento utilizo inner join para ir juntando las tablas, y al juntar el código de los procedures, (el nuevo y del que dependía antes), encuentro que no me filtra bien, aunque eso si, va mucho más rápido. El código que me funciona, aunque lento es:
Donde el código del procedimiento renopla2 es el siguiente:
El nuevo que estoy montando es:
El cual, supuestamente tendría que ser la unión de los otros dos. No me filtra por el select count, ¿que estoy haciendo mal? ¿hay forma de forzar indices a un procedimiento? alguien me puede ayudar?? Muchas gracias Virginia |
Hola.
El hecho de unir los dos procedimientos en uno solo, te va a proporcionar un aumento mínimo del rendimiento. Yo no lo haría, sobretodo cuando está claro que tienes un problema de falta de índices.(Saltarse el procedimiento almacenado, solo valdria la pena si quieres pasar de un rendimiento de, pongamos 1.5 segunos a 1.0 segundos, pero no es el caso). Tienes que estudiar el plan de ejecución de cada una de las consultas involucradas. Te va a indicar el índice que se utiliza para cada tabla y unión involucrada en la consulta. Lo primero que tienes que buscar es tablas donde te muestre NATURAL, aquí te está indicando que esa tabla no se optimiza con ningún índice. (En caso de que todas las tablas utilizen un índice, entonces tendrás que buscar que índice es de poca ayuda en la consulta, y sustituirlo por un índice compuesto de varios campos). Además puedes utilizar un depurador de procedimientos almacenados. Ejecutando línea a línea el procedimiento almacenado, vas a ver en que línea se pierde el rendimiento. Utiliza SQL'92 y no SQL'89 (creo). Estás creando un producto cartesiano : Código:
select distinct Saludos. |
Hola,
Cita:
Cita:
Cita:
Cita:
¿donde estoy creando un producto cartesiano? Perdona pero, ¿me lo puedes aclarar algo más? Muchas gracias por todo, Virginia |
Cita:
La versión personal es gratuita Cita:
Cita:
Si no usas joins, lo que estás creando es un producto cartesiano. En este caso entre renopla2 y grupos. |
Hola cadetill,
Cita:
Cita:
Cita:
Muchas gracias, Virginia |
Hola.
Cita:
El plan de ejecución consta de la lista de índices que se utilizan para optimizar la consulta. Para más información sobre los planes de ejecución puedes utilizar la herramienta IbPLANAnalyzer http://delphi.weblogs.com/IBPLANalyzer Cita:
select XXX from Tabla1, Tabla2 Deberias especificar el tipo de unión de las tablas mediante un Inner Join o un Left Outer Join. select XXX from Tabla1 inner join Tabla2 on Tabla1.Campo1 = Tabla2.Campo2 (consulta la documentación de Interbase para mas detalles del inner y outer join) Cita:
Saludos. |
Respecto a los planes de ejecución. En IB-Expert tienes una pestaña al cargar un procedimiento almacenado, llamada 'Plan Analyzer', en ella se muestran en forma de árbol los planes de las consultas del procedimiento.
NOTA: Aunque me parece que esto no está disponible en la versión gratuita. Saludos. |
Hola,
Vale, me he bajado el trial de la versión completa del IbExpert, y el IbPLANAnalyzer. He descubierto, que hay algo que no necesitaba, y que me cargaba mucho el procedimiento. En cualquier caso, ahora no me funciona correctamente el código de : Código:
where (( select count (*) from alumnos inte Código:
select distinct exte.NUMALU, (exte.NOMALU || ' ' || exte.APELALU) AS NOMBRE, Código:
where (( select count (*) from alumnos inte Muchas gracias por vuestra paciencia, Virginia |
La franja horaria es GMT +2. Ahora son las 21:56:10. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi