Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Pasar Registros de Query a una Tabla (https://www.clubdelphi.com/foros/showthread.php?t=9737)

JamesBond_Mx 30-04-2004 17:17:04

Pasar Registros de Query a una Tabla
 
Hola compañeros, Tengo una pequeña duda, a ver si es posible que me ayuden, Tengo un query al cual le aplico un filtro, quiero pasar los registros obtenidos de este filtro a una tabla temporal, ¿como puedo hacer esto? o en su defecto, ¿puedo aplicar varios filtros a un query, me refiero a que una vez que apliqué un filtro, a ese query filtrado aplicarle otro filtro, y asi sucesivamente hasta cuatro filtros distintos, hice ciertos cálculos y las diferentes combinaciones de filtros que necesito hacer son 560 filtros¡¡¡, Ejemplificaré lo que quiero hacer a ver si es posible

Tengo un Form con cuatro diferentes ComboBox el primer combo tiene 4 posibles valores, el segundo tiene 7 posibles valores, el tercero tiene 4 posibles valores y el cuarto tiene 5 posibles valores esto me dá 4*7*4*5=560 combinaciones posibles, bueno hasta ahi esta bien no hay problema, el problema es para aplicar esos filtros a un query, se me ocurrió primero filtrar el query, con el primer combo y ya una vez filtrado volverlo a filtrar por el valor del segundo combo, pero no funciona una vez aplicado el segundo filtro el primero se desaparece, ahora otra opcion es la de crear dos tablas temporales, en la primera vaciaría los valores del primer filtro aplicado al query, y depues filtrar esta tabla y vaciar los registros filtrados a la tabla dos, al mismo tiempo que la vacio, una vez hecho esto, filtro la tabla 2 con el tercer valor del combo, y paso los registros a la tabla 1 nuevamente (que se habia vaciado), por ultimo aplico el cuarto filtro a la tabla 1 nuevamente y es como obtendría el verdadero resultado que necesito.

¿como ven?, ¿estoy bien?, o ¿puede haber otra opción?.

Por su atención muchas gracias. :D

jachguate 30-04-2004 17:40:19

Yo creo que es mucho mejor opción armar el Select "al vuelo" con cualquier combinación de las cuatro condiciones aplicables, asignarlo a la propiedad SQL del query y abrirlo.

Hasta luego.

;)

JamesBond_Mx 30-04-2004 19:12:13

Resolví el problema, haciendo lo de las tablas temporales.

Gracias.

roman 30-04-2004 19:15:47

Algo complicado ¿no? Como dice jachguate simplemente tienes que armar al vuelo una consulta SELECT construyendo la condición WHERE de acuerdo a los valores de los Combos. Pienso que además el rendimiento será mucho más eficiente.

// Saludos

JamesBond_Mx 30-04-2004 19:28:40

Lo porbaré, pero que pasa si en las opciones de los combos hay una que no es valor que exista en la tabla, por ejemplo, la palabra "Todos", esto me indicaría que quiero todos los registros de este campo, pero si el Query busca el valor "todos", dentro de la tabla, obviamente que no va a encontrar nada y la consulta me la va a regresar vacía, Por ejemplo digamos:

El primer Combo se selecciona la opción X (que si existe como valor en la tabla)
El segundo Combo Elijo La Opción Y (Que también Existe)
El tercer Combo se elige La Opción "Todos" (Esta no existe)
Y el cuarto Combo Se elige la opcion Z (que también existe)

Por culpa de la tercera opción el Query me saldría Vació, y no es ese el resultado esperado.

Me explique??

roman 30-04-2004 19:36:32

Cita:

Empezado por JamesBond_Mx
Me explique??

No. Porque el resultado sí es el esperado conforme a tu mensaje original. Tú hablaste de hacer "filtros sobre filtros", aplicar un filtro a lo ya filtrado.

En el ejemplo que expones, al aplicar el tercer filtro sobre los dos anteriores es entonces lógico que no te de resultados no habiendo registros que satisfagan la condición.

¿No estás confundiendo ors con ands? Tal como lo planteaste en el primer mensaje las condiciones de cada combo se unen con una conjunción lógica AND- debe cumplir todas las condiciones. Quizá lo que buscas es unirlos con un OR- cumple alguna de las condiciones.

// Saludos

JamesBond_Mx 30-04-2004 19:51:33

Bueno, Trataré de explicarmen mejor
El query lo hago En Base a 4 Campos, El campo estado, el cual en la tabla de donde toma los datos tiene dos posibles valores, Corregida y Pendiente, yo agrego una tercera opción que sería Todos, donde quiero decir que quiero que me traiga todos los registros de la tabla sin importar su estado, para empezar si elijo esta tercera opción ya el query saldría vacio, y no es eso lo que quiero, pues lo que quiero es que primero tome todos los registros existentes. Ahora supongamos que eligo un valor valido para el primer campo, digamos Corregida, para el segundo campo El cual se llama Supervisor, existen Seis valores posibles, que son 6 nombres de personas, pero también como en el primero agrego una opción más que es Todos, digamos que mi tabla tiene 1202 registros de estos 550 son corregidas, si yo elijo el valor Todos para el segundo campo, el Query queadría vacío, puesto que no existe en la tabla ningún valor Todos , y cosa que sería falsa pues existen 550 registros, y lo mismo ocurriría con los otros dos campos.

Espero haberme dado a entender.

roman 30-04-2004 19:55:06

Pues simplemente a la hora de construir la condición del WHERE te fijas si el combo dice Todos y en tal caso excluyes la condición sobre el campo estado de la consulta.

// Saludos

JamesBond_Mx 30-04-2004 19:57:23

En eso habia pensado y es lo que estoy probando en este momento precisamente, o sea si el valor es Todod, que no filtre el Query, y se vaya al siguiente campo y así. en cadena... estoy haciendo pruebas.

Gracias.

JamesBond_Mx 30-04-2004 23:30:28

De plano no puedo, como puedo hacer para que no me tome encuenta la condición de Todas si es elegida, y me jeute la consulta bien??? ya me desesperé... :(

roman 01-05-2004 00:25:43

Vamos a ver. Según lo que entiendo (corrígeme si me equivoco) tienes cuatro combos correspondientes a cuatro campos de tu tabla, digamos campo1, campo2, campo3 y campo4. La consulta debe mostrarte los registros que satfisfagan las cuatro condiciones, a saber:

campo1 = combo1.text
campo2 = combo2.text
campo3 = combo3.text
campo4 = combo4.text

Esto quiere decir que tu consulta debe ser del estilo de:

Código SQL [-]
select * from tabla
where
  campo1 = ? and
  campo2 = ? and
  campo3 = ? and
  campo4 = ?

donde los símbolos ? representan los valores de los combos.

Ahora bien, tú quieres que al seleccionar la opción todos de uno de los combos te seleccione todos los registros que satisfagan las otras tres condiciones pero indistintamente de cuál sea el valor del campo correspondiente a todos.

Lo único que tienes que hacer, al momento de construir la cadena SQL es entonces omitir la condición correspondiente. Por ejemplo, si todos corresponde al combo 2 entonces ahora la consulta será:

Código SQL [-]
select * from tabla
where
  campo1 = ? and
  campo3 = ? and
  campo4 = ?

Cuál de las dos escoges lo decides con un condicional:

Código Delphi [-]
if combo2.text <> 'todos' then
   primera consulta
else
  segunda consulta

¿Está más claro?

// Saludos

JamesBond_Mx 03-05-2004 14:27:02

Pues si, asi estaba pensado, pero... ¿cuantas combinaciones posibles hay? tu me das la posibiliadad para una sola combinacion, pero veamos esto.
Pueden darse las siguientes combinaciones

Código:


Opción1  Opción 2  Opción 3    Opción 4

Todos      X          X          X
Todos    Todos        X          X
Todos    Todos      Todos          X
Todos    Todos      Todos        Todos
.
.
.
etc.

Si mis cálculos no me fallan hay 4*4*4*4 Posibles combinaciones o sea 256, te imaginas son 256 Consultas distintas no es tan facil.

roman 03-05-2004 16:34:53

Precisamente por eso es la idea de consruir al vuelo la consulta. Claro que tendrás que utilizar algunos condicionales debido al "valor" todos pero nunca tantos cómo 4*4*4*4.

// Saludos

JamesBond_Mx 03-05-2004 20:21:29

Bueno si tienes razón, no serían las 256, seria solo en el caso en que se seleccionara la opcion todos en cualquiera de las 4 opciones y sus combinaciones pero solo en las que sea seleccionada la opción "Todos"... voy a ver

roman 04-05-2004 08:29:31

Me parece que te estás liando demasiado debido a que piensas que hay que tratar muchos casos pero en realidad no es así.

Al construir la consulta SQL tienes que fijarte cómo contribuye cada combo a la condición where. Cada combo puede contribuir de dos maneras, no 4, ni 5 ni 7, sólo dos:
  • nada - si comboN.text = 'todos'
  • campoN = comboN.text - si comboN.text <> 'todos'

Es decir, si un combo tiene 'todos' por texto, no contribuye a la consulta pues quiere decir que no impones ninguna condición sobre él.

Esto implica cuatro condicionales- uno tras otro.

La construcción del condicional where (es decir, las sentencias después de where) es un poco enredada debido a que las condiciones de los distintos combos deben estar unidas por un conector and y por cada combo debes fijarte si realmente hay necesidad de poner and:
Código Delphi [-]
// whereStr es una cadena temporal para almacenar el condicional

if whereStr = '' then // no hay condiciones previas
begin
  (* agregar condición sólo si combo.text no es 'todos' *)
  if comboN.text <> 'todos' then
    whereStr := 'campoN = ' + QuotedStr(comboN.text);
end
else // hay condiciones previas - hace falta AND
  (* agregar condición sólo si combo.text no es 'todos' *)
  if comboN.text <> 'todos' then
    whereStr := whereStr + ' and ' + QuotedStr(comboN.text);
y necesitarás uno de estos bloques por cada combo. Con esto sería más que suficiente pero como a mi me da flojera leer este tipo de código te lo voy a complicar un poco:

Código Delphi [-]
// whereStr es una cadena temporal para almacenar el condicional

if whereStr = '' then // no hay condiciones previas
begin
  if comboN.text <> 'todos' then
    whereStr := 'campoN = ' + QuotedStr(comboN.text)
  else
    whereStr := '1 = 1';
end
else // hay condiciones previas - hace falta AND
  if comboN.text <> 'todos' then
    whereStr := whereStr + ' and ' + QuotedStr(comboN.text)
  else
    whereStr := whereStr + ' and ' + '1 = 1';
La extraña condición '1 = 1' es una condición que siempre se cumple por lo que el efecto es el mismo: no imponer condición alguna sobre el campo.

En principio parece una complicación innecesaria (y quizá lo sea) pero el hecho de que cada combo siempre contribuya con algo me permite simplificar la lógica de cuándo agregar el and pues sé de fijo que lo agrego después del primer, segundo y tercer combo quedando así ya con todos los combos:

Código Delphi [-]
if combo1.text <> 'todos' then
  whereStr := 'campo1 = ' + QuotedStr(combo1.text)
else
  whereStr := '1 = 1';

if combo2.text <> 'todos' then
  whereStr := whereStr + 'and ' + 'campo2 = ' + QuotedStr(combo2.text)
else
  whereStr := whereStr + 'and ' + '1 = 1';

if combo3.text <> 'todos' then
  whereStr := whereStr + 'and ' + 'campo3 = ' + QuotedStr(combo3.text)
else
  whereStr := whereStr + 'and ' + '1 = 1';

if combo4.text <> 'todos' then
  whereStr := 'campo4 = ' + QuotedStr(combo4.text)
else
  whereStr := whereStr + 'and ' + '1 = 1';

Pero más aún, como los cuatro condicionales son esencialmente iguales podemos definir una función:

Código Delphi [-]
function CondicionCampo(Campo, Valor: String): String;
begin
  if Valor = 'todos'
    then Result := '1 = 1'
    else Result := Campo + ' = ' + QuotedStr(Valor);
end;

que los construya genéricamente con lo cual reducimos el código a:

Código Delphi [-]
whereStr := CondicionCampo('campo1', combo1.text);
whereStr := whereStr + ' and ' + CondicionCampo('campo2', combo2.text);
whereStr := whereStr + ' and ' + CondicionCampo('campo3', combo3.text);
whereStr := whereStr + ' and ' + CondicionCampo('campo4', combo4.text);
Y listo. Ya sólo tienes que agregar esto al resto de la cadena SQL, por ejemplo:

Código Delphi [-]
Query.Sql.Text := 'select * from tabla where ' + whereStr;

Yo colocaría esto en un evento OnChange común a los cuatro combos.

// Saludos

jachguate 04-05-2004 10:41:05

Yo lo veo mas sencillo tadavia...

Código Delphi [-]
Var
  YaWhere : Boolean;

  Procedure AddWhere(condicion : String);

  Begin
    if YaWhere Then
      Query1.SQL.Add('and ' + condicion)
    else begin
      Query1.SQL.Add('where ' + condicion);
      YaWhere := True;
    end;
  End;

Begin
  YaWhere := False;
  Query1.SQL.Clear;
  Query1.SQL.Add('Select * from tabla');
  if combo1.Text <> 'todos' then
    AddWhere('campo1 = ' + QuotedStr(combo1.Text));
  if combo2.Text <> 'todos' then
    AddWhere('campo1 = ' + QuotedStr(combo2.Text));
  if combo3.Text <> 'todos' then
    AddWhere('campo1 = ' + QuotedStr(combo3.Text));
  if combo4.Text <> 'todos' then
    AddWhere('campo1 = ' + QuotedStr(combo4.Text));
  Query1.Open;
end;

Hasta luego.

;)

roman 04-05-2004 16:08:38

Pues qué te digo, aún con el truco me gusta más el mío:

Código Delphi [-]
procedure TForm1.combo1Change(Sender: TObject);
  function CondicionCampo(Campo, Valor: String): String;
  begin
    if LowerCase(Valor) = 'todos'
      then Result := '1 = 1'
      else Result := Campo + ' = ' + QuotedStr(Valor);
  end;

var
  whereStr: String;

Begin
  whereStr := CondicionCampo('campo1', combo1.text);
  whereStr := whereStr + ' and ' + CondicionCampo('campo2', combo2.text);
  whereStr := whereStr + ' and ' + CondicionCampo('campo3', combo3.text);
  whereStr := whereStr + ' and ' + CondicionCampo('campo4', combo4.text);
  Query1.SQL.Text := 'select * from tabla where ' + whereStr;
end;

En gustos se rompen géneros :cool:


La franja horaria es GMT +2. Ahora son las 00:49:35.

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