Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-04-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
Seleccion multiple para montar query

Hola a tod@s,

estoy atascado dándole vueltas a este tema pero no tengo nada claro como solventarlo y que sea ágil, por lo que os pido ayuda nuevamente sobre ideas o procesos que se os ocurran....

En un grid (asociado a un ClientDataSet) tengo un campo temporal "seleccionado" para que el usuario escoja la tienda (1.200 registros) sobre los que lanzar una segunda qry que realiza cálculos, hasta aquí todo bien. El problema lo tengo a la hora de cómo montar el segundo qry en función de las tiendas que se hayan seleccionado.

Hasta ahora estaba pensando en recorrer el cdsTDAS y en función del campo "seleccionado" (boolean) ir guardando el codigo de la tienda para luego montar la qry con las tiendas seleccionadas, algo así :
Código Delphi [-]
procedure TFDlgSlccionMltple.BtnOkClick(Sender: TObject);
var
  Marca : TBookmark;
begin
  isqlselmult := '';
  with cdsTDAS do
  begin
    DisableControls;
    Marca := GetBookMark;
    try
      First;
      while not cdsTDAS.EOF do begin
        if FieldByName('tmp_select').AsBoolean then
        begin
          if (isqlselmult = EmptyStr) then
          begin
            isqlselmult := 'com = ' + cdsTDAS.fieldbyname('com').AsString + ' ';
          end else begin
            isqlselmult := isqlselmult + 'com = ' + cdsTDAS.fieldbyname('com').AsString + ', or ';
          end;
        end;
        Next;
      end;
    finally
      GoToBookmark(Marca);
      FreeBookmark(Marca);
      EnableControls;
    end;
  end;
end;

pero aquí tengo algunas dudas,
1.- se podría montar un query como el siguiente o habría limitaciones ?? :
Código SQL [-]
select campo1, campo2, campo3 from tbPrtesDia where (cdgotda = XXXX, or cdgotda= XXX1, or cdgotda=XXAX,..... )//etc, etc.... pueden ser 1200 cdgo!!!

2.- cómo puedo eliminar el último "', or '" de la qry que voy montando??


3.- no me parece la mejor consulta del mundo pero no se me ocurre o conozco otra forma de optimizarla.

no se si me he explicado correctamente, agradecería vuestra ayuda, se admiten propuestas

Saludos y Gracias
__________________
Toni | blog
Responder Con Cita
  #2  
Antiguo 22-04-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
el código de arriba está mal, sorry por no depurarlo, el que funciona correctamente es :

Código Delphi [-]
procedure TFDlgSlccionMltple.BtnOkClick(Sender: TObject);
var
  Marca : TBookmark;
begin
  isqlselmult := '';
  with cdsTDAS do
  begin
    DisableControls;
    Marca := GetBookMark;
    try
      First;
      while not cdsTDAS.EOF do begin
        if FieldByName('tmp_select').AsBoolean then
        begin
          if (isqlselmult = EmptyStr) then
          begin
            isqlselmult := 'centro = ' + cdsTDAS.fieldbyname('com').AsString;
          end else begin
            isqlselmult := isqlselmult + ' or centro = ' + cdsTDAS.fieldbyname('com').AsString;
          end;
        end;
        Next;
      end;
    finally
      GoToBookmark(Marca);
      FreeBookmark(Marca);
      EnableControls;
    end;
  end;
end;

lanza la consulta correctamente y no tarda mucho la verdad es que me ha sorprendido....

las dudas 1 y 2 ya están resueltas pero sigo teniendo la duda de si consideráis que es la mejor forma de hacerlo.

gracias y saludos
__________________
Toni | blog
Responder Con Cita
  #3  
Antiguo 22-04-2010
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Opcion 1:

Si el campo tmp_select no es temporal (está en la tabla), podrías hacer algo asi:

- Marcas la tabla de selección
- Luego haces este select:
Código SQL [-]
select campo1, campo2, campo3 from tbPrtesDia 
where (cdgotda in (select tienda from tabla_seleccion where tmp_select=1))

En principio no tiene límite de cuantas tiendas están seleccionadas

Opcion 2:

También puedes generar el sql, de una forma parecida a la que ya haces:
Código SQL [-]
select campo1, campo2, campo3 from tbPrtesDia 
where (cdgotda in (XXX1,XXX2,XXX3,XXX4,...))

Deberás probar los límites de la base de datos que utilices.
No se si te permitirá hacer un sql muy largo o si te permitirá tantos "or" , si seleccionas todas las tiendas.
Responder Con Cita
  #4  
Antiguo 22-04-2010
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.410
Poder: 22
fjcg02 Va camino a la fama
Te sugiero un pequeño cambio que puede que te facilite las cosas.
Incluye una opción para que lo que tú selecciones lo incluya o excluya. Claro, la generación de la select será diferente en cada caso.

Pienso que un usuario que tenga que seleccionar de esa lista, una de dos. O selecciona todas o sólamente un grupo. De esta manera seguramente la select te saldrá más corta. Aunque ya te digo, que el usuario seleccione entre 1200 registros, puede ser un infierno. Concretamente yo, si una lista tiene más de 30 registros, soy incapaz de hacer nada con ella.

Un saludo
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
  #5  
Antiguo 22-04-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
gracias duilioisola y [fjcg02] por las respuestas,

lamentablemente el campo "seleccionado" es un temporal en el ClientDataSet.

El proceso es el siguiente :
1.- tienen una ventana de selección con 3 dbgrid dónde se agrupan esos registros en función de la zona de venta, director de venta y tienda. Pero no puedo utilizar esas agrupaciones de zona de venta o director de venta ya que en la tabla de partes no se conserva esa relación.
2.- la selección de las tiendas puede ser en función de varios criterios, o bien por los agrupamientos del punto 1 o bien seleccionándolas de forma aleatoria manualmente por lo que no me queda otra que recorrer la tabla de tiendas para saber cuáles han seleccionado.

duilioisola, respecto a esa qry, no se me había ocurrido pasarle todos valores en una sola validación como indicas, eso debo probarlo
hasta ahora está funcionando con la qry que dije al principio (la de tantos "or ...").

sigo probando y os cuento, pero si veis algo que se pueda mejorar no dudéis en decirlo

Saludos
__________________
Toni | blog
Responder Con Cita
  #6  
Antiguo 22-04-2010
Avatar de eflosten
eflosten eflosten is offline
Miembro
 
Registrado: abr 2010
Posts: 24
Poder: 0
eflosten Va por buen camino
Si quieres seguir con los OR yo tuve un problema parecido hace poco, lo solucioné usando una cadena, que era la condición autogenerada, e incrustandola en el SQL.

Código Delphi [-]
if Cadena='' then Cadena:='Campo='+valor;
else cadena:=Cadena+' or Campo='+valor;
DataSet.SQL:='SELECT FROM (todo lo que vaya aqui) WHERE '+Cadena;

Y con respecto a la multiselección, por qué no haces un Array dinámico en el evento que sea necesario (OnSelectRow quizá? no tengo el delphi delante para mirar xD) con los registros que selecciones, luego es solo hacer un bucle for.
Responder Con Cita
  #7  
Antiguo 22-04-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
gracias eflosten por la respuesta,

muestro el proceso completo para que se entienda mejor, un código vale más que mil palabras, sobre todo si son mías

este es el resultado de una form modal dónde se hace la selección de las tiendas :
Código Delphi [-]
procedure TFDlgSlccionMltple.BtnOkClick(Sender: TObject);
var
  Marca : TBookmark;
begin
  isqlselmult := ''; //variable pública dónde guardo los datos del where
  with cdsTDAS do
  begin
    DisableControls;
    Marca := GetBookMark;
    try
      First;
      while not cdsTDAS.EOF do begin
        if FieldByName('tmp_select').AsBoolean then
        begin
          if (isqlselmult = EmptyStr) then
          begin
            isqlselmult := 'centro = ' + cdsTDAS.fieldbyname('com').AsString;
          end else begin
            isqlselmult := isqlselmult + ' or centro = ' + cdsTDAS.fieldbyname('com').AsString;
          end;
        end;
        Next;
      end;
    finally
      GoToBookmark(Marca);
      FreeBookmark(Marca);
      EnableControls;
    end;
  end;
end;

esta es la llamada a mostrar la form modal de selección de las tiendas y la cadena completa del qry con los where :
Código Delphi [-]
procedure TFInfrmes_SupSelect.btn5Click(Sender: TObject);
begin
  with TFDlgSlccionMltple.Create(self) do begin
    try
      if ShowModal = mrok then
      begin
        {consulta DETALLE ACUMULADOS}
        isqldetsel := 'SELECT centro, max(fecha) as fecha, cdgodiet, sec_to_time(SUM(time_to_sec(hllmndo))) AS rhllmndo, ' +
              'SUM(visitas) AS rvisitas, SUM(motnotot) AS rmotnotot, SUM(visitas) + SUM(motnotot) AS rcntctos, ' +
              'SUM(motno01) AS rmotnotot01, SUM(motno02) AS rmotnotot02, SUM(motno03) AS rmotnotot03, SUM(motno04) AS rmotnotot04, ' +
              'SUM(motno05) AS rmotnotot05, SUM(motno06) AS rmotnotot06, SUM(motno07) AS rmotnotot07,  SUM(motno08) AS rmotnotot08, ' +
              'SUM(motno09) AS rmotnotot09,  SUM(motnoes02) AS rmotnototes01, SUM(motnoes02) AS rmotnototes02, ' +
              'SUM(segllam) AS rsegllam, SUM(vllamdec) AS rvllamdec, SUM(llamtot) AS rllamtot, SUM(impventas) AS rimpventas ' +
              'FROM tb03P WHERE ((fecha between :fdesde and :fhasta) AND (' + isqlselmult +'))' +
              'GROUP BY tb03P.centro ' +
              'order by tb03P.centro, tb03P.fecha desc;';
      end;
    finally
      Free;
    end;
  end;
end;

lanzo el qry de cálculos :
Código Delphi [-]
//en otro evento se lanza .....
  with zroqryinfrme_sup do
  begin
    Close;
    sql.Clear;
    SQL.Add(isqldetsel);  //esta es la consulta montada manualmente con la seleccion
    ParamByName('fdesde').AsDate    := dteeddtefdesde.Date;
    ParamByName('fhasta').AsDate    := dteeddtefhasta.Date;
    Open;

    if zroqryinfrme_sup.RecordCount = 0 then
    begin
      MessageDlg('No se han encontrado registros en las Fechas seleccionadas.', mtWarning, [mbOK], 0);
      zroqryinfrme_sup.Close;
      dteeddtefdesde.SetFocus;
    end;
  end;

haciendo pruebas he seleccionado las 1.200 tiendas y el qry de resultados ha tardado menos de 4 segundos en calcular los datos de los partes (150 registros ahora mismo), teniendo en cuenta que es un mysql remoto vía adsl... como lo véis ??

lo que me da miedo es el día que la tabla de los partes tenga miles de registros y seleccionen todas las tiendas....

se admiten sugerencias
__________________
Toni | blog
Responder Con Cita
  #8  
Antiguo 22-04-2010
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Se me ocurre una tercera solución.
- Crea una tabla que contenga el código de las tiendas
- Muestras el Grid y dejas que el usuario seleccione las que desee.
- Recorre el grid e inserta las seleccionadas en la tabla.
- Luego puedes hacer un join o un select como el que te he mencionado más arriba.
Código SQL [-]
select campo1, campo2, campo3 from tbPrtesDia 
where (cdgotda in (select tienda from tabla_seleccion))
Responder Con Cita
  #9  
Antiguo 22-04-2010
Avatar de tgsistemas
tgsistemas tgsistemas is offline
Miembro
 
Registrado: dic 2003
Ubicación: Barcelona
Posts: 149
Poder: 21
tgsistemas Va por buen camino
ummm así a primera vista, creo que en términos globales, el proceso será más lento, no??
__________________
Toni | blog
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
seleccion multiple cyber_zero Varios 2 26-06-2008 17:22:33
Selección Múltiple de Items en un ListView Rolo Varios 6 31-08-2007 21:28:58
Selección multiple con TCheckBox Nelly Varios 1 09-08-2007 00:28:06
selección múltiple en dbgrid davidgaldo Conexión con bases de datos 2 16-04-2004 15:15:04


La franja horaria es GMT +2. Ahora son las 16:56:06.


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
Copyright 1996-2007 Club Delphi