Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Buscar valores mas cercanos (https://www.clubdelphi.com/foros/showthread.php?t=70224)

Toni 08-10-2010 00:14:37

Buscar valores mas cercanos
 
Hola compañeros,

Tengo la necesidad de buscar en una tabla (firebird) por un campo que es numerico y tengo que buscar en un momento determinado los valores mas 'proximos'. Por proximos quiero decir los valores que se hacercan mas a un valor, tanto por delante como por detras.

Ejemplo:

Si tengo una tabla con el campo1 de tipo integer y con estos datos.

Campo1
-------
1
2
3
4
5
6
7
8
9
10

Como podria buscar o obtener la tabla ordenada por el criterio de proximidad a un valor, por ejemplo del 5:

Campo1
--------
4
6
7
3
8
2
9
1
10

En otros servidores SQL me permite realizar una consulta donde la clausula order by puedo poner una expresion con un calculo y esto permite obtener el resultado deseado:

select Campo1 from Tabla
order by abs(Campo1 - :Valor)

Lo que no se como realizar esto en firebird.


Saludos,

guillotmarc 08-10-2010 11:27:50

Hola.

¿ Porqué no utilizas esto ? :

select Campo1, abs(Campo1 - :Valor)
from Tabla
order by 2

Naturalmente en tu programa Delphi tendrás que ocultar la segunda columna y solo mostrar la primera.

Saludos.

Toni 08-10-2010 12:25:37

Hola Guillotmarc,

Pues no habia caido en esa posibilidad de utilizar el order by por numero de columna y poner la expresion en la select.

Lo estoy probando y me da un error que no me permite utilizar la funcion abs(), yo diria que la he utilizado en otras ocasiones. Lo estoy probando con FB1.5 y el EMS IB Manager 3. Me da la impresion que es el gestor EMS que no le gusta la funcion y no el propio FB1.5

guillotmarc 08-10-2010 14:20:12

Hola.

Lo he mirado y parece que no es una función interna, sino que está en la UDF ib_udf.dll

Prueba declarándola, ejecutando primero (solo hay que hacerlo una vez) :

DECLARE EXTERNAL FUNCTION abs
DOUBLE PRECISION
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'IB_UDF_abs' MODULE_NAME 'ib_udf';


NOTA : Esta declaración es para FB 2.0, espero que no haya cambiado para FB 1.5.

guillotmarc 08-10-2010 14:22:46

Claro que siempre puedes hacer esta consulta.

select Campo1,
case when (Campo1 - :Valor) > 0 then Campo1 - :Valor else -1 * (Campo1 - :Valor) end
from Tabla
order by 2

Pero la verdad es que es muy feo.

mightydragonlor 08-10-2010 19:13:26

y no es mejor usar un Between?, lo digo por que es lo que uso en MSSQL, en firebird no sé si está.

rgstuamigo 08-10-2010 22:04:30

Pues no entiendo por que complicarse tanto, ya que el amigo Toni, él mismo a dado la solucion a su problema;).
Personalmente no trabajo con Firebird, pero segun tengo entendido, ya es un servidor bien madurito, por tanto creo que tranquilamente se puede hacer ésta consulta SQL:
Código SQL [-]
select Campo1 from Tabla
order by Abs(Campo1 - 5);
Particularmente la he probado en MySQL y he obtenido el siguiente resultado:
Cita:

Campo1
5
4
6
3
7
2
8
1
9
10
Saludos...:)

guillotmarc 09-10-2010 12:10:49

Cita:

Empezado por rgstuamigo (Mensaje 378809)
Particularmente la he probado en MySQL y he obtenido el siguiente resultado:

En Firebird 1.5, que es el servidor utilizado por Toni, esta consulta no es aceptada. En versiones superiores de Firebird sí que se ha implementado la posibilidad de utilizar expresiones en la cláusula ORDER BY.

rgstuamigo 09-10-2010 14:57:46

Ah Caray... entonces quizás nuestro buen amigo Toni debería actualizarse a la última version de Firebird, que segun tengo entendido es la version 2.5;)
Por demás queda decir que Firebird es "gratis", por lo tanto en lo posible hay que trabajar con las últimas versiones.;)
Saludos...:)

Casimiro Notevi 09-10-2010 15:01:13

Cita:

Empezado por guillotmarc (Mensaje 378868)
En Firebird 1.5, que es el servidor utilizado por Toni, esta consulta no es aceptada. En versiones superiores de Firebird sí que se ha implementado la posibilidad de utilizar expresiones en la cláusula ORDER BY.

Efectivamente, en firebird 1.5 no funciona, pero lo he probado en firebird 2.1 y sí funciona.

Toni 11-10-2010 23:36:23

muchas gracias a todos por la colaboracion. Probare a migrar a FB2.1.

guillotmarc 12-10-2010 11:35:26

Cita:

Empezado por Toni (Mensaje 379010)
muchas gracias a todos por la colaboracion. Probare a migrar a FB2.1.

Si vas a migrar, ya puedes hacerlo directamente a FB 2.5, que hace pocas semanas ya fue liberado como versión final.

Aunque prepárate para revisar todo tu proyecto, ya que muchas consultas que en FB 1.5 te funcionaban pueden necesitar que las reescribas (por ejemplo, por campos sin especificar su tabla, etc. ... ya que FB 2.x es más estricto con seguir el estándar SQL).

NOTA: para hacer el cambio de una base de datos a otra, tienes que hacer un backup de tus bases de datos en FB 1.5, desinstalarlo e instalar FB 2.5, y posteriormente restaurar tus copias de seguridad. Aunque si tienes dos ordenadores disponibles, casi que te recomiendo que instales FB 2.5 en el segundo ordenador, y restaures allí tus copias de seguridad. De esa forma podrás trabajar a la vez con FB 1.5 y FB 2.5.

Saludos.

Toni 28-10-2010 18:52:48

Muchas gracias Guillotmarc, finalmente he podido probar en real la solucion que me propusistes y me funciona correctamente.

Código:

select Campo1,
case when (Campo1 - :Valor) > 0 then Campo1 - :Valor else -1 * (Campo1 - :Valor) end
from Tabla
order by 2

Cuando tenga ocasion de migrar a FB2.5 mirare de utilizar una expresion mas elegante, pero por el momento va a las mil maravillas.

Mil gracias.

Saludos,


La franja horaria es GMT +2. Ahora son las 14:07:08.

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