Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Select anidados (https://www.clubdelphi.com/foros/showthread.php?t=65174)

jaimeh 25-11-2009 19:33:25

Select anidados
 
Hola a todos

Si tengo una tabla con dos campos: Tiques y Codigos

quiero obtener una consulta que saque Tiques que tengan 3 mismos codigos

Ejemplos Tiques que tengan los 1000,1001,1002
Tiques Codigos
1 1000
1 1001
1 1002
1 1003
2 1000
2 1002
3 1000
3 1001
3 1002

Tendría que darnos
Tiques
1
3

Yo creo que se hace con Select Anidados pero por vueltas que
estoy dando a los anidamientos no lo consigo

A ver si alguien tiene alguna idea y me puede ayudar

Muchas gracias a todos

afunez2007 25-11-2009 20:44:35

La Solucion es esta:

Código SQL [-]
SELECT     TIQUES, COUNT(TIQUES) AS CUENTA
FROM         Table_1
GROUP BY TIQUES
HAVING      (COUNT(*) > 2)

te dara como resultado
TIQUES CUENTA
1 4
3 3

Saludos

jaimeh 25-11-2009 21:23:05

Muchas gracias por responderme

No me explique del todo bien. Estoy usando Firebird y en la tabla
los tiques no tienen porque ir seguidos pueden ser totalmente diferentes al
igual que los codigos que también pueden ser diferentes no me valdrían los
mayor y menor que
tiene que ser algo genérico

hay que tener en cuenta que la tabla va a tener miles de tiques y de
Codigos
tienen que cumplir la condicion de que haya un tique para estos 3 codigos

Ejemplos Tiques que tengan los 1050,1024,1030
Tiques Codigos
5 1050
5 1024
3 1030
5 1080
6 1050
6 1030
5 1030
3 1050
3 1024
4 1024
4 1050
4 1100
4 1200


daría

Tique
5
3


Muchas gracias

jaimeh 25-11-2009 21:30:43

Habia pensado en algo parecido a esto

Código SQL [-]

      'Select DISTINCT t1.Tique, t1.Codigo from CODIGOSFIN as t1 ' +
      ' where Codigo = 1050 ' +
                                'AND Exists ' +
     '(Select t1.Tique from CODIGOSFIN where Codigo = 1024) ' +

//                                 'AND Codigo IN ' +
//      '(Select Codigo from CODIGOSFIN where Codigo = 3)) ' +
      'Order By Tique';


Claro que me da mal

Muchas gracias

afunez2007 25-11-2009 22:07:59

Pues todavia no entiendo bien lo que quieres hacer, se me ocurre esto: Ingrese esa tabla de datos que pusiste y probe el siguiente codigo:

Código SQL [-]
SELECT DISTINCT TIQUE FROMCODIGOSFIN WHERE CODIGO=1050 OR (CODIGO=1024) or (CODIGO=1030)

y me devuelve lo siguiente:
TIQUE
3
4
5
6

jaimeh 25-11-2009 23:00:58

es que eso no valdría

Tendría que dar
Tique
5
3

el 5 cumple la condicion de que tiene un Codigo 1050 y un Codigo 1030 y
un codigo 1024

y el 3 lo mismo

espero haberme explicado un poco mejor

Saludos

afunez2007 25-11-2009 23:22:18

Ahora voy entendiendo que es lo que quieres hacer, depues de varias pruebas creo que la solucion seria asi:

Código SQL [-]
SELECT  TIQUE,COUNT(TIQUE) AS CUENTA FROM CODIGOSFIN  WHERE CODIGO=1024 or CODIGO=1030 or CODIGO=1050    GROUP BY TIQUE HAVING COUNT(*)=3

Esto devuelve:
TIQUE CUENTA
--3------3----
--5------3----

jaimeh 26-11-2009 00:01:10

Eso es lo mismo que antes

al final lo he hecho con delphi y parece que funciona
algo parecido a esto

Código Delphi [-]

    tblCodigosFin.Open;
    tblCodigosFin.IndexFieldNames := 'TIQUE;CODIGO';

  list := TStringList.Create;
  list.Add('1');
  list.Add('3');
  list.Add('5');

  listSeleccionado := TStringList.Create;

  TiqueAnterior := '';
  tblCodigosFin.First;
  while not tblCodigosFin.Eof do
  begin

    Tique := tblCodigosFin.FieldByName('Tique').AsString;
    Codigo := tblCodigosFin.FieldByName('Codigo').AsInteger;

    if Tique <> TiqueAnterior then
    begin
//       TiqueAnterior := Tique;

       if listSeleccionado.Count =
          list.Count then
       begin

         tblSeleccion.Append;
         tblSeleccion.FieldByName('Tique').AsString := TiqueAnterior;
//       tblSeleccion.FieldByName('Codigo').AsInteger := Codigo;
         tblSeleccion.Post;
       end;

       listSeleccionado.Clear;
       TiqueAnterior := Tique;

    end
    else begin
       if list.IndexOf(IntToStr(Codigo)) >= 0 then
         if listSeleccionado.IndexOf(IntToStr(Codigo)) < 0 then
           listSeleccionado.Add(IntToStr(Codigo));

    end;



    tblCodigosFin.next;
  end;


Gacias a todos y saludos

afunez2007 26-11-2009 00:09:43

Bien siempre hay distintas formas de hacer, las cosas aunque utilizaste un metodo mas largo, podrias optimizarlo utilizando una query con el codigo que te envie, ya que me parece que seria mas rapido que utilizar un ciclo que recorra la tabla, ya que mencionaste que tenia muchos registros

Saludos

Axel_Tech 26-11-2009 09:51:07

No la he probado pero creo que la consulta correcta sería algo así:
Código SQL [-]
SELECT DISTINCT TIQUE 
FROM CODIGOSFIN A 
WHERE EXISTS (SELECT TIQUE FROM CODIGOSFIN B WHERE A.TIQUE=B.TIQUE AND CODIGO=1050)
AND EXISTS (SELECT TIQUE FROM CODIGOSFIN B WHERE A.TIQUE=B.TIQUE AND CODIGO=1024)
AND EXISTS (SELECT TIQUE FROM CODIGOSFIN B WHERE A.TIQUE=B.TIQUE AND CODIGO=1030) 
ORDER BY TIQUE

rgstuamigo 27-11-2009 20:18:20

Esta creo que tambien Funciona;):
Código SQL [-]
Select distinct Tiques from CodigosFin cf
Where Codigos in(1050,1024,1030)
and (Select count(cf.Tiques)from CodigosFin aux where cf.Tiques=aux.Tiques)>=3;
Saludos...:)

jaimeh 04-12-2009 20:26:40

Muchas gracias a todos por contestarme

Pensaba que ya se había acabado el hilo y por eso no volví a mirarlo.

Lo de Axel si funciona , yo había pensado algo por el estilo pero no sabía como implementarlo. Lo que si, es que es mas lento que haciéndolo sólo
con delphi. He hecho algo como lo siguiente porque
podrían ser para 100 códigos o más


Código Delphi [-]

  list := TStringList.Create;
  list.Add('1');
  list.Add('3');
  list.Add('5');



   qrySeleccion.SQL.Clear;
   qrySeleccion.SQL.Add(
     'SELECT DISTINCT Tique ' +
     'FROM CODIGOSFIN A ' +
     'WHERE EXISTS ' +
       ' (SELECT TIQUE FROM CODIGOSFIN B WHERE A.TIQUE=B.TIQUE ' +
       ' AND CODIGO= ' + list[0] + ' ) ');

   for i := 1 to list.Count -1 do
     qrySeleccion.SQL.Add(
      ' AND EXISTS ' +
        ' (SELECT TIQUE FROM CODIGOSFIN B WHERE A.TIQUE=B.TIQUE ' +
        ' AND CODIGO= ' + list[i] + ' ) ');


     qrySeleccion.SQL.Add('ORDER BY TIQUE, CODIGO');

     qrySeleccion.Open;


Lo de tuAmigo lo he probado aunque no lo entiendo muy bien y para
mas de 100 códigos se podría complicar la cosa.
Código SQL [-]
     'Select distinct Tiques from CodigosFin cf ' +
     ' Where Codigo in(1,3,5) ' +
     ' and (Select count(cf.Tique) from CodigosFin aux ' +
        ' where cf.Tique=aux.Tique)>=3 ';


Me da un error:
Cannot use un aggregate function in a where clause, use habing instead


Y lo que hice yo tiene un pequeño bug que lo he solucionado

Código Delphi [-]
  tblCodigosFin.First;
  while not tblCodigosFin.Eof do
  begin

    Tique := tblCodigosFin.FieldByName('Tique').AsString;
    Codigo := tblCodigosFin.FieldByName('Codigo').AsInteger;

    if Tique <> TiqueAnterior then
    begin
//       TiqueAnterior := Tique;

       if listSeleccionado.Count =
          list.Count then
       begin

         tblSeleccion.Append;
         tblSeleccion.FieldByName('Tique').AsString := TiqueAnterior;
//       tblSeleccion.FieldByName('Codigo').AsInteger := Codigo;
         tblSeleccion.Post;

       end;

       listSeleccionado.Clear;
       TiqueAnterior := Tique;

    end;

       if list.IndexOf(IntToStr(Codigo)) >= 0 then
         if listSeleccionado.IndexOf(IntToStr(Codigo)) < 0 then
           listSeleccionado.Add(IntToStr(Codigo));


    tblCodigosFin.next;
  end;

        if listSeleccionado.Count =
          list.Count then
       begin

         tblSeleccion.Append;
         tblSeleccion.FieldByName('Tique').AsString := TiqueAnterior;
//       tblSeleccion.FieldByName('Codigo').AsInteger := Codigo;
         tblSeleccion.Post;

       end;


ahora si me da bien y es bastante rápido

Muchas gracias a todos y pido disculpas por no haber contestado antes

rgstuamigo 05-12-2009 15:01:15

Cita:

Empezado por jaimeh (Mensaje 348187)
...
Pensaba que ya se había acabado el hilo y por eso no volví a mirarlo.
...

En realidad un hilo en el Club Delphi nunca termina:eek::D, siempre hay personas quienes quieren agregar algo.;)... Y quien mas que tú, para estar pendiente y atento al hilo que iniciaste.;)

Cita:

Empezado por jaimeh (Mensaje 348187)
...
Lo de tuAmigo lo he probado aunque no lo entiendo muy bien y para
mas de 100 códigos se podría complicar la cosa.
...

Bueno no acabo de entenderte :o, primero dices que solo quires buscar para tres específicos códigos(1050,1024,1030), ahora ya dices que van a ser mas de 100 códigos:rolleyes:, pues entonces mas bien te convendria sacar todos los Tiques que se repiten 3 o mas veces algo asi:
Código SQL [-]
Select distinct Tiques from CodigosFin cf
where(Select count(cf.Tiques)from CodigosFin aux where cf.Tiques=aux.Tiques)>=3;
Saludos...:)

jaimeh 08-12-2009 20:34:13

Gracias por respoderme amigo

al principio puse un ejemplo de lo que tenía que dar el select para un caso particular esperando una respuesta de un algoritmo para n códigos, que puede que no me expresara bien del todo. La idea de axel era como yo lo pensaba pero no sabía escribirlo.
Al final lo que hice fue modificar lo de axel y funciono, aunque volviera hacerlo para tres códigos 1,3,5 (list) en el ejemplo pero ese algoritmo funciona para n códigos, es el algoritmo que puse mas arriba.

En tu algoritmo amigo no pones los codigos que se van a mirar que pueden ser n códigos de números.

De todas formas gracias por dedicarme tiempo amigo

saludos a todos


La franja horaria es GMT +2. Ahora son las 09:15:31.

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