FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
es posible este tipo de consulta?
hola a todos...
resulta que la clave primaria de mis registros esta compuesta por dos numeros... llamemos a estos numeros a y b estos dos numeros los puedo generar con una formula y con el resultado otros mas segun un criterio que tengo... aplicando la formula en iteraciones obtengo un conjunto de pares de numeros que conforman la clave... por ejemplo (1,2) - (5-7) - (10-20) ... donde el primer numero seria a y el segundo b ahora la pregunta es la siguiente : es posible select REGISTRO from tabla where (a,b) in ({1,2},{5,7},{10,20}) ...? comento que en este momento obtengo los resultados de la siguiente forma ...que funciona select REGISTRO from TABLA where (a=1 and b=2) or (a=5 and b=7) or(a=10 and b=20)... pero si aumento los numeros la consulta se vuelve muy larga y se incrementan los tiempos de evaluacion... alguien tendria una consulta mas eficiente ? |
#2
|
||||
|
||||
hasta donde yo sé, (que no sé mucho ), el operador in solo permite un valor, es decir:
where (a in (1,5,10)) and (b in (2,7,20) pero claro, te traería tambien el (1,7) que no es lo que quieres. Si dices la base de datos y motor que usas, bde, ado, etc. Igual se podría hacer un algo para traducir a cadenas de texto. No sé si es posible, pero la idea es hacer algo así:
Un saludo
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. |
#3
|
||||
|
||||
Hola manos,
lo que pides no puede hacerse como dices. Tendrás que ingeniártelas para generar tu query. Me imagino que sabrás cuántos pares de números tienes en el momento de ejecutar la sentencia y sería hacer una cosa más o menos como esta:
Más o menos. Que cuánto más pares tienes más va a tardar...eso ya lo sé pero como lo tienes montado no se me ocurre otra cosa. Un saludo. |
#4
|
|||
|
|||
Hola foro,
Como me gustan los procedimientos almacenados !. Me puse en la tarea de hacer un ejercicio completo, espero te sea de utilidad y puedes implementar la idea para tu aplicacion facilmente. El ejemplo esta en Firebird, implementable en Oracle y SQL-Server. No se si se puede hacer con mySQL. La restriccion UK_CONDICIONES es para evitar que coloques mas de una vez la misma condicion de busqueda. Se puede definir la tabla condiciones sin el campo id como identificador, si se desea que todas las condiciones en la tabla pasen al procedimiento almacenado. La ventaja con el identificador es que se puede jugar a rangos de condiciones. Tablas: CREATE TABLE DATOS ( CAMPO_1 INTEGER NOT NULL, CAMPO_2 INTEGER NOT NULL, CAMPO_3 VARCHAR(10) NOT NULL ); CREATE TABLE CONDICIONES ( ID SMALLINT NOT NULL, CAMPO_1 INTEGER NOT NULL, CAMPO_2 INTEGER NOT NULL ); Restricciones: ALTER TABLE DATOS ADD CONSTRAINT PK_DATOS PRIMARY KEY (CAMPO_1, CAMPO_2); ALTER TABLE CONDICIONES ADD CONSTRAINT PK_CONDICIONES PRIMARY KEY (ID); ALTER TABLE CONDICIONES ADD CONSTRAINT UK_CONDICIONES UNIQUE (CAMPO_1, CAMPO_2); Datos: INSERT INTO DATOS (CAMPO_1, CAMPO_2, CAMPO_3) VALUES (1, 2, 'A'); INSERT INTO DATOS (CAMPO_1, CAMPO_2, CAMPO_3) VALUES (5, 7, 'B'); INSERT INTO DATOS (CAMPO_1, CAMPO_2, CAMPO_3) VALUES (10, 20, 'C'); INSERT INTO DATOS (CAMPO_1, CAMPO_2, CAMPO_3) VALUES (10, 7, 'D'); INSERT INTO DATOS (CAMPO_1, CAMPO_2, CAMPO_3) VALUES (10, 1, 'E'); INSERT INTO DATOS (CAMPO_1, CAMPO_2, CAMPO_3) VALUES (5, 1, 'F'); COMMIT WORK; INSERT INTO CONDICIONES (ID, CAMPO_1, CAMPO_2) VALUES (1, 1, 2); INSERT INTO CONDICIONES (ID, CAMPO_1, CAMPO_2) VALUES (2, 5, 7); INSERT INTO CONDICIONES (ID, CAMPO_1, CAMPO_2) VALUES (3, 10, 20); COMMIT WORK; El procedimiento: SET TERM ^ ; ALTER PROCEDURE SP_SI_ES_POSIBLE ( CONDICION_INICIAL INTEGER, CONDICION_FINAL INTEGER) RETURNS ( CAMPO_1 INTEGER, CAMPO_2 INTEGER, CAMPO_3 VARCHAR(10)) AS begin /* Selecciona el rango de condiciones */ for select campo_1, campo_2 from condiciones where id between :condicion_inicial and :condicion_final into :campo_1, :campo_2 do begin /* Busca los registros que cumplan la condicion */ for select campo_3 from datos where campo_1 = :campo_1 and campo_2 = :campo_2 into campo_3 do begin suspend; end end end ^ SET TERM ; ^ Como serian las consultas: Para una condicion (no tendria mucho sentido): select * from sp_si_es_posible (2,2); Todas las condiciones (para tan pocas condiciones es mejor la opcion que colocaste en el foro) : select * from sp_si_es_posible (1,3); Para muchas condiciones (si se te simplificaria el trabajo !!!) : select * from sp_si_es_posible (1,50); Lo anterior suponiendo que tienes 50 condiciones por las cuales buscar. Muchos exitos.
__________________
Luis Fernando Buelvas T. |
#5
|
|||
|
|||
Que pena que no sabia colocar etiquetas, ahi va el procedimiento almacenado:
__________________
Luis Fernando Buelvas T. |
#6
|
||||
|
||||
si los numeros de tu clave primaria tienen un rango definido podrias probar a multiplicar uno de ellos por un múltiplo de 10 mayor al rango y le sumas el otro campo por ejemplo
Código:
SELECT REGISTRO FROM tabla where (a*1000)+b in ( 1002, 5007, 10020); |
#7
|
||||
|
||||
Me ha gustado mucho la idea de droguerman
ea, queda dicho. Un saludo
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. |
#8
|
|||
|
|||
Hola foro,
Parece que la solucion que sugerí requiere mucha elaboracion, la solucion de droguerman es completamente aplicable si el numero de registros no es alto, ya que el plan del motor de base de datos (cualquiera que sea) sería recorrer la tabla de manera natural (de comienzo a fin). Otra posible solucion y siquiendo un poco la linea de droguerman es crear un campo fisico en la BD (campo_auxiliar) y que puede ser mantenido por triggers (before insert y before update) con la formula de droguerman. El campo deberia estar indexado, por aquello del rendimiento que tanto me preocupa. campo_auxiliar = (a*1000) + b; y la consuta SELECT REGISTRO FROM tabla where campo_auxiliar in ( 1002, 5007, 10020);
__________________
Luis Fernando Buelvas T. |
|
|
|