Jump to content


Photo

Manipular condiciones de consulta


  • Please log in to reply
10 replies to this topic

#1 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3486 posts
  • LocationMexico City

Posted 10 November 2012 - 12:32 PM

Buenas tardes a todos, aquí andamos con una pregunta sobre una consulta  *-)

Resulta que tengo una consulta en Firebird  a una sóla tabla y con 6 condiciones en el where los cuales los controlo por medio de parámetros desde Delphi. Lo que espero recibir de la consulta es simplemente si existen registros concordantes o no (al menos 1)... hasta aquí todo bien.

Lo que me tiene dando vueltas la cabeza es que me piden saber, en caso de que la consulta no encuentre ningún registro concordante,  cuál o cuáles de los 6 parámetros fue el que hizo que la consulta resultara vacía...

Se me ocurrió ir metiendo parámetro por parámetro de la siguiente manera:

1. Abrir la consulta únicamente con la primera condicion. Si arroja registros, determinar que ese parámetro no afecta la consulta y agregarle otra condición. Si no, quitar la condición de la consulta y determinar que ese parámetro sí afecta a la consulta.
2. Agregar el segundo parámetro y hacer el mismo procedimiento que con el punto 1.

.... y así sucesivamente ...

:embarrassed:

Aunque creo que sí funcionará mi idea, me parece digamos que... "poco elegante" y quiero saber si existe un método más directo o no tan loco como el que se me ocurrió  :D :D :D

Les agradezco su ayuda a todos ;)

Saludox ! :)
  • 0

#2 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4266 posts
  • LocationCosta Rica

Posted 10 November 2012 - 12:40 PM

Hola
Seria bueno ver la consulta, aunque parezca vano o los novatos nos gusta ver.... *-)
Saludos
  • 0

#3 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1092 posts
  • LocationMurcia, España

Posted 10 November 2012 - 01:19 PM

Antes de ponerte a hacer nada, mejor piensa esto: no tiene solución lo que te piden!

Imagina los números del 1 al 6 y estas seis condiciones: que no sea el 1, que no sea el 2, y así hasta que no sea el 6.

Si haces tu consulta, no sale ningún número, pero ninguna de las 6 condiciones por sí sola fue la "culpable", como se dice por aquí, todos la mataron y ella sola se murió.

Lo más que podrías obtener que tenga sentido es el mínimo subconjunto de condiciones que da un resultado vacío, pero eso implica probar todas las combinaciones... 2^6 en total, 64, y quedarte con la combinacion que de vacío y tenga el mínimo número de condicones activas. Un lio tremendo.

Una idea más liviana y que no se van a dar cuenta (si no se dieron cuenta de que te pedían un imposible no notarán la diferencia) es buscar condicones indispensables: QUITAS la condición 1 y pruebas con las otras 5, y si deja de ser vacío, esa la marcas como "necesaria". Repites con las demás y tendras las "imprescindibles", que podría no ser ninguna, claro!
  • 0

#4 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3486 posts
  • LocationMexico City

Posted 12 November 2012 - 09:30 AM

Pues ésta es la consulta que pretendo manipular:


select count(*)
  from ctrac_clasif
where fraccion starting with :fraccion
  and num_part = :parte
  and cve_impo = :cliente
  and cve_prov = :proveedor
  and pai_orig = :pais
  and imp_exp = :operacion


Si la consulta resultara en 0 me gustaría saber cuál o cuáles condiciones provocaron ese valor

Saludox ! :)
  • 0

#5 mightydragon_lord

mightydragon_lord

    Advanced Member

  • Miembros
  • PipPipPip
  • 73 posts

Posted 12 November 2012 - 10:08 AM

Yo realmente veo poco útil esto, pero puedes hacerlo con IF EXISTS() con todas las combinaciones en el caso que la consulta principal no retorne resultados.
  • 0

#6 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3486 posts
  • LocationMexico City

Posted 12 November 2012 - 10:15 AM

Yo realmente veo poco útil esto, pero puedes hacerlo con IF EXISTS() con todas las combinaciones en el caso que la consulta principal no retorne resultados.


Puede ser... pero el que paga manda y si es lo suficientemente insistente... pues... qué nos queda ???  :

Gracias por la sugerencia, qué hace exactamente el IF EXISTS amigo ???

Saludox ! :)
  • 0

#7 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 posts
  • LocationEspaña

Posted 12 November 2012 - 10:39 AM

Buenas,

Vista la consulta y el nombre de los campos, entiendo que no hay ningún tipo de relación entre ellos. Si así fuera, y dado que son todo "AND", con lanzar 6 consultas (una para condición) tendrías suficiente para saber cuál hace que la query no retorne resultados.

Eso sí, siempre tendrás que comprobar las 6 consultas dado que puede ser una, más de una o todas las condiciones las que provoquen que no retorne resultados.

Nos leemos
  • 0

#8 seoane

seoane

    Advanced Member

  • Administrador
  • 1259 posts
  • LocationEspaña

Posted 12 November 2012 - 10:55 AM

Pueden haber 2^6=64 combinaciones de consultas, no son demasiadas, así que en ultima instancia siempre podemos hacer un bucle y recorrer las 64 combinaciones viendo cuales retornan un resultado y cuales no:

Este ejemplo es con un StringList, pero en tu caso habría que reemplazarlo por la propiedad SQL de tu consulta, y donde pone "Condicion 1", "Condicion 2", etc ... poner la condicion correspondiente.


delphi
  1. var
  2.   i: Integer;
  3. begin
  4.   with TStringList.Create do
  5.   try
  6.     for i:= 0 to $3F do
  7.     begin
  8.       Clear;
  9.       if i and 1 > 0 then
  10.         Add('Condicion 1');
  11.       if i and 2 > 0 then
  12.         Add('Condicion 2');
  13.       if i and 4 > 0 then
  14.         Add('Condicion 3');
  15.       if i and 8 > 0 then
  16.         Add('Condicion 4');
  17.       if i and 16 > 0 then
  18.         Add('Condicion 5');
  19.       if i and 32 > 0 then
  20.         Add('Condicion 6');
  21.       // Aqui ejecutas la consulta y ves si arroja resultados
  22.     end;
  23.   finally
  24.     Free;
  25.   end;
  26. end;


  • 0

#9 fredycc

fredycc

    Advanced Member

  • Moderadores
  • PipPipPip
  • 874 posts
  • LocationOaxaca, México

Posted 12 November 2012 - 11:02 AM

Creo aquí me imaginaré un poco, pues nunca he usado una tabla temporal en firebird, sería bueno saberlo  ^o|, alguién que nos ilumine por favor. Bueno la idea es algo así.

1.- Creo una tabla temporal con los siguientes datos:

   

      SELECT COUNT(*)
      FROM ctrac_clasif
      WHERE fraccion starting WITH :fraccion
   


2.- Verificar que haya registros en ella, si no los hay: el parámetro fracción afecta la consulta -> fin

3.- Consultamos los datos temporales y así sucesivamente.
   

      SELECT COUNT(*)
      FROM tabla_temporal
      WHERE num_part = :parte
   


El objetivo aquí es obtener una muestra a través de una tabla temporal y empezamos a filtrar según los demás parámetros hasta que simplemente encontremos el culpable  ^o| ó se ejecute sin problemas y esta misma tabla nos devuelva los datos.

Saludos
  • 0

#10 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3486 posts
  • LocationMexico City

Posted 12 November 2012 - 11:13 AM

:shocked: me gusta la idea de mi amigo seoane (muy abstracta  :) !)...

Buenas,

Vista la consulta y el nombre de los campos, entiendo que no hay ningún tipo de relación entre ellos. Si así fuera, y dado que son todo "AND", con lanzar 6 consultas (una para condición) tendrías suficiente para saber cuál hace que la query no retorne resultados.

Eso sí, siempre tendrás que comprobar las 6 consultas dado que puede ser una, más de una o todas las condiciones las que provoquen que no retorne resultados.

Nos leemos


El problema de ésto es que si hago una consulta exclusiva con cada parámetro puede ser que TODAS arrojen resultados, ya que la información si existe en la tabla, pero la combinación AND de todas es la que puede producir que la consulta devuelva un 0, es por eso que si la cosa viene más bien el lado de las combinaciones...

Estoy ideando una solución y probaré las que aquí han propuesto... les platico el resultado  (y)

Gracias a todos... sóis los mejores  ;)

Saludox ! :)

P.D. Como bien dice mi amigo seoane... no doy por cerrado el hilo, se aceptan más y más ideas  (y)
  • 0

#11 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1092 posts
  • LocationMurcia, España

Posted 13 November 2012 - 09:19 AM

Me reitero: no tiene solución, aunque te paguen por ello.

¿Porqué no hay chinos en Perú con coleta larga y con un Ferrari azul?

¿porque no hay chinos en Perú? no.
¿porque los chinos no tiene nunca coleta? no.
¿porque sus coletas nunca son largas? no.
¿porque no tienen Ferraris? no.
¿porque jamas compran Ferraris azules? no.

¿Entonces?

Simplemente porque ninguna persona existente cumple con todas las condiciones a la vez, y no hay mucho más que añadir.

Lo más que podrías intentar, como ya te comenté, es a ir eliminando condiciones 1 a 1 hasta que no sea vacío el resultado, y las que desactivaste, esas en su conjunto hacen que no aparezcan resultados: chinos y con ferrari y en Perú, no existen.

Pero si quitas condiciones en otro orden, obtienes otro resultado: en Perú con un ferrari azul no hay nadie.

Encontraras, en general, varias combinaciones que te dan vacío, y ninguna es especial.

Si quieres de todas formas meterte en el lio, yo usaria una SQL de esta forma:


SELECT COUNT(*)
  FROM ctrac_clasif
WHERE
  ((fraccion starting WITH :fraccion) or (:cond1=0))
  AND ((num_part = :parte) or (:cond2=0))
  AND ((cve_impo = :cliente) or (:cond3=0))
  AND ((cve_prov = :proveedor) or (:cond4=0))
  AND ((pai_orig = :pais) or (:cond5=0))
  AND ((imp_exp = :operacion) or (:cond6=0))


Ahora puedes hacerle un prepare para que sea rápido y probar todas las combinaciones:



delphi
  1. Qry.prepare;
  2.  
  3. //Valores iniciales:
  4. for i:= 1 to 6 do
  5.   Qry.Params[i].AsInteger:= 1;
  6.  
  7. //Analizo todas las combinaciones:
  8. for i:= 1 to 6 do begin
  9.   for j=1 downto 0 do begin
  10.     Qry.Params[i].AsInteger:= j;
  11.     Qry.EcexQuery;
  12.     if (Qry.Fields[0].AsInteger = 0) then begin
  13.       //Esta combinación da vacio, los que están a 1 son los culpables, imprimela o almacenala leyendo los 6 params.values
  14.       ShowMessage(Qry.Params[1].AsString+' '+Qry.Params[2].AsString+' '+ etc...);
  15.     end;
  16.     Qry.close;
  17.   end;
  18. end;



Bueno, el código es "de memoria", algo fallara seguro, pero la idea es que encontraras igual 6 o 7 combinaciones de condiciones "culpables", no hay una condición sola que sea la culpable (igual si, ya es cosa de suerte).
  • 0




IP.Board spam blocked by CleanTalk.