Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Ayuda con SQL (https://www.clubdelphi.com/foros/showthread.php?t=81663)

marcial 05-12-2012 11:02:19

Ayuda con SQL
 
Hola a todos:
Trabajo con D5 y Firebird 2.1 (Componentes FIBPLUS aunque creo que con cualquier componente se podría hacer lo que necesito)
Mi problema es el siguiente:

En la pantalla de "Entrada de lineas de Albarán" tengo entre otras una Tabla Clientes y otra Lineas. Un DBGrid1 para las lineas de Albarán que voy introduciendo y un DBGrid2 que saca los articulos que se ha llevado antes ese cliente.

En el fichero de Lineas se van almacenando todas las lineas de Albarán, es decir, que p.ej. del articulo 1 hay almacenadas a lo largo del tiempo 40 lineas con su fecha, documento, cantidad, precio de venta y Cliente.

TABLA LINEAS---------------------
Descripcion Docmto Cantidad Precio Fecha Cliente
BACON AHUMADO 125 1 4,15 16.11.2012 158
BACON AHUMADO 126 7 4,18 20.11.2012 158
BACON AHUMADO 180 4 4,10 30.11.2012 158
MAGRO TERNERA 125 8 8,90 16.11.2012 158
MAGRO TERNERA 140 3 8,75 28.11.2012 158
MAGRO TERNERA 190 2 9,40 01.12.2012 160 <---- ojo, es ya otro cliente

Necesitaria que cuando teclee el código del cliente me aparecieran en el DBGrid2 una linea por cada artículo pero que sea el último introducido para ver a que precio y que cantidad se llevó la última vez, es decir, que cuando selecciones el cliente 158 me aparezca en el DBGrid2

BACON AUMADO 180 4 4,10 30.11.2012 158
MAGRO TERNERA 140 3 8,75 28.11.2012 158

y el DBGrid1 en blanco listo para la introducción de nuevas Lineas.

Estoy hecho un lio porque el DBGrid1 apunta a LINEAS, y el DBGrid2 tambien pues los dos DBGrid acceden al mismo fichero, el 1 añadiendo lineas y el 2 clasificando. Pido ayuda para ver si alguien me podría decir como seria la sentencia SQL que tendría que usar.

Espero haberme explicado y muchisimas gracias por vuestro tiempo.
Marcial

Faust 05-12-2012 21:08:56

Podrías ser más claro en tu explicación :o

marcial 06-12-2012 00:23:06

Tengo una tabla LINEAS que contiene multiples registros con los campos codigo,descripcion,precio,cliente y fecha de venta; y necesito saber cual es el precio del último registro de cada articulo que ha consumido un determinado cliente.

El contenido de la tabla Lineas es el siguiente:
Articulo: 1 // Descripcion: Bacon // Precio: 10,00 // Fecha 10.10.2012 // Cliente: 20
Articulo: 2 // Descripcion: Salmon // Precio: 4,00 // Fecha 12.10.2012 // Cliente: 21
Articulo: 1 // Descripcion: Bacon // Precio: 9,80 // Fecha 15.10.2012 // Cliente 20
Articulo: 2 // Descripcion: Salmon // Precio: 4,15 // Fecha 18.10.2012 // Cliente: 20

Si quiero saber lo que ha consumido el cliente 20, me deberia de aparecer en un dbgrid:

Articulo: 1 Descripcion: Bacon Precio: 9,80 Fecha: 15.10.2012 <------- Último precio del cliente 20 articulo 1
Articulo: 2 Descripcion: Salmon Precio: 4,15 Fecha: 18.10.2012 <--------Último precio del cliente 20 articulo 2

Espero haberme explicado con más claridad

Faust 06-12-2012 00:49:28

Ah en el SQL haz un "ORDER BY FECHA DESC" en conjunto con un GROUP BY Articulo... ahorita no lo puedo probar pero chécalo

celades1 06-12-2012 13:19:10

Hola

creo que seria esto

Código SQL [-]
select a.descripcio,a.codigo,max(a.fecha),
avg((select a.precio from lineas where codigo=a.codigo and cliente=:cliente 
and fecha=(select max(fecha) from lineas where codigo=a.codigo and cliente=:cliente))) 
from lineas a 
where a.cliente=:cliente
group by a.descripcio,a.codigo

Panta

Gallosuarez 06-12-2012 16:19:36

Posible solución ...
 
Marcial:

Creo que esto es lo que quieres ...
Código SQL [-]
SELECT *
FROM LINEAS
WHERE CLIENTE = ID_CLIENTE_QUE_QUIERES
ORDER BY FECHA_CLIENTE DESC
ROWS 1 TO 10

La instrucción ROWS limita el número de resultados a los diez primeros ... ¿me explico}

Atte:
Gerardo Suárez Trejo

PD. No dejes de comentar como te fue ...

Casimiro Notevi 06-12-2012 16:45:40

Creo que este hilo es lo que necesitas.

marcial 07-12-2012 09:06:43

Hola Celades1,Gallosuarez y Casimiro
Muchas Gracias por contestar.

Faust, Celades1 y Gallosuarez: No puedo probarlo hasta el Lunes (o a lo mejor el Sabado). Seguro que cuando lo pruebe comento algo.

Casimiro: He visto el hilo que dices pero, aparte de que no lo entiendo demasiado bien, lo he probado y pone "Max(Precio) as Precio,", con lo que me está dando el máximo precio y no el último, por lo que no me sirve así, y creo Firebird no tiene la sentencia (Ultimo).

Ya os diré algo cuando lo pruebe.

olbeup 07-12-2012 09:41:17

Hola marcial,

Que tal esta SQL:
Código SQL [-]
SELECT
    DESCRIPCION
    ,DOCMTO
    ,CANTIDAD
    ,PRECIO
    ,FECHA
    ,CLIENTEID
  FROM Lineas
  WHERE FECHA IN
          (
            SELECT
                MAX(FECHA)
              FROM Lineas
              GROUP BY DESCRIPCION, CLIENTEID
          )
        AND CLIENTEID = 158

Un saludo.

ecfisa 07-12-2012 18:51:53

Hola marcial.
Cita:

Empezado por marcial (Mensaje 451382)
...y creo Firebird no tiene la sentencia (Ultimo).

No, pero podes obtener el último registro de este modo:

Código SQL [-]
SELECT SKIP ((SELECT COUNT(*) - 1 FROM TABLA)) * FROM TABLA

Saludos.

olbeup 07-12-2012 19:21:29

Cita:

Empezado por ecfisa (Mensaje 451414)
Hola marcial.

No, pero podes obtener el último registro de este modo:

Código SQL [-]
SELECT SKIP ((SELECT COUNT(*) - 1 FROM TABLA)) * FROM TABLA

Saludos.

No creo que no has leído ecfisa el anunciado de marcial, lo que pretende marcial, es visualizar todos los artículo que se ha llevado el cliente x, que muestre el último precio del la última fecha agrupados por producto.

La SQL que le he puesto, es la correcta.

Un saludo.

ecfisa 07-12-2012 19:38:45

Hola olbeup.

Si he leído todo el hilo.

Si lees con mas atención mi mensaje anterior, verás que es una respuesta puntual a un comentario de marcial sobre obtener el último/ultimos registros en Firebird.

De ningún modo tiene la pretensión de ser solución al problema inicial. No descalifica ni es una alternativa a tu sentencia SQL.

Saludos.

marcial 08-12-2012 14:02:26

1 Archivos Adjunto(s)
Hola a todos:
Aunque tengo que agradecer a todos vuestro aporte, tengo que decirle a Olbeup que el resultado no es el deseado. Tiene que ser un matiz que no doy con el. Os adjunto el resultado con el dódigo de Olbeup para ver si se puede retocar. La Imagen de la izda es el fichero completo de lineas y la de la derecha deberían ser los codigos comprados por el cliente 5191 y deberían ser sólo cuatro lineas:

BACON AHUMADO precio: 3,42 Fecha: 05.12.2012 Documento: 60
JAMON FRESCO SIN HUESO precio: 3,25 Fecha: 05.12.2012 Documento: 61 (En el docmto hay dos apuntes al Jamon)
CODILLO DE CERDO precio: 2,40 Fecha: 05.12.2012 Documento: 61
PANCETA FRESCA CON HUESO precio: 2,22 Fecha: 05.12.2012 Documento: 61

el código utilizado es:
Código Delphi [-]
Lineas1.Active := True;
SQL1 := 'SELECT DESCRIPCION ,DOCUMENTO ,CANTIDAD ,PRECIOVENTA , FECHA ,CODCLIENTE, SERIE, ARTICULO, HORAGRABACION ' +
       'FROM Lineas ' +
       'WHERE FECHA IN(SELECT MAX(FECHA) FROM Lineas GROUP BY DESCRIPCION, CODCLIENTE) ' +
        'AND CODCLIENTE = ''' + Edit4.Text + '''';
CONSULTAQUERYLINEAS;

El programa de Albaranes tiene un DBGrid a la izquierda con el pedido que me va haciendo ESE dia el cliente(sobre el Fichero LINEAS), y el DBGrid de la derecha debe contener TODOS los articulos que se ha llevado antes para que yo los vea y se los vaya recordando por telefono con su último precio.(Tambien sobre Fichero LINEAS). Por eso he puesto otro dataset Lineas1 para que al ejecutar el SQL me deje correctos los dos DBGRID (uno sobre cada dataset) que en realidad son los dos sobre el mismo fichero.

Gracias a todos por vuestro tiempo y esfuerzo.

Gallosuarez 08-12-2012 18:51:42

¿Probaste mi código? ...
 
Marcial:

Veo que hablas del códigos de los demás, sin embargo no encuentro ninguna referencia al mio. ¿Ya lo probaste? (No lo desprecies solo por pensar que es una simple sentencia SQL). Haz un "copy-paste" del código que publiqué y nos cuentas (no te va a llevar mas de 2 minutos).

Saludos,

marcial 08-12-2012 19:28:28

Gallosuarez:
Siento mucho que hayas pensado que he despreciado tu codigo por ser una sentencia SQL. Yo no desprecio ningun código de nadie que sabe más que yo.
He probado tu código y lo que pasa es que me aparecen 10 columnas del fichero de lineas, pero no guardan la relación que yo deseo, que es la última de cada articulo (fecha y hora) comprado por el cliente que sea.
Si no he mencionado a todos los que tan amablemente me habeis prestado ayuda, lo siento, pero es porque trato de arreglar el problema con los códigos que me poneis y estoy prueba que prueba con la lengua fuera.
Pido perdón humildemente a todos.
Marcial

olbeup 09-12-2012 03:38:15

Cita:

Empezado por marcial (Mensaje 451466)
Hola a todos:
Aunque tengo que agradecer a todos vuestro aporte, tengo que decirle a Olbeup que el resultado no es el deseado. Tiene que ser un matiz que no doy con el. Os adjunto el resultado con el dódigo de Olbeup para ver si se puede retocar. La Imagen de la izda es el fichero completo de lineas y la de la derecha deberían ser los codigos comprados por el cliente 5191 y deberían ser sólo cuatro lineas:

BACON AHUMADO precio: 3,42 Fecha: 05.12.2012 Documento: 60
JAMON FRESCO SIN HUESO precio: 3,25 Fecha: 05.12.2012 Documento: 61 (En el docmto hay dos apuntes al Jamon)
CODILLO DE CERDO precio: 2,40 Fecha: 05.12.2012 Documento: 61
PANCETA FRESCA CON HUESO precio: 2,22 Fecha: 05.12.2012 Documento: 61

el código utilizado es:
Código Delphi [-]Lineas1.Active := True;
SQL1 := 'SELECT DESCRIPCION ,DOCUMENTO ,CANTIDAD ,PRECIOVENTA , FECHA ,CODCLIENTE, SERIE, ARTICULO, HORAGRABACION ' +
'FROM Lineas ' +
'WHERE FECHA IN(SELECT MAX(FECHA) FROM Lineas GROUP BY DESCRIPCION, CODCLIENTE) ' +
'AND CODCLIENTE = ''' + Edit4.Text + '''';
CONSULTAQUERYLINEAS;




El programa de Albaranes tiene un DBGrid a la izquierda con el pedido que me va haciendo ESE dia el cliente(sobre el Fichero LINEAS), y el DBGrid de la derecha debe contener TODOS los articulos que se ha llevado antes para que yo los vea y se los vaya recordando por telefono con su último precio.(Tambien sobre Fichero LINEAS). Por eso he puesto otro dataset Lineas1 para que al ejecutar el SQL me deje correctos los dos DBGRID (uno sobre cada dataset) que en realidad son los dos sobre el mismo fichero.

Gracias a todos por vuestro tiempo y esfuerzo.

Hola marcial,

Efectivamente tienes razón, y he realizado otra SQL que hace lo que pide.

Código SQL [-]
SELECT
    L1.ARTICULO
    ,L1.DESCRIPCION
    ,L1.CODCLIENTE
    ,(SELECT
          MAX(FECHA)
        FROM Lineas
        WHERE ARTICULO = L1.ARTICULO
     ) FECHAULTIMA
    ,(SELECT TOP 1
          PRECIOVENTA
        FROM Lineas
        WHERE ARTICULO = L1.ARTICULO
        ORDER BY FECHA DESC
     ) ULTIMOPRECIO
    ,(SELECT TOP 1
          HORAGRABACION
        FROM Lineas
        WHERE ARTICULO = L1.ARTICULO
        ORDER BY FECHA DESC
     ) HORAGRAB
    ,(SELECT TOP 1
          DOCUMENTO
        FROM Lineas
        WHERE ARTICULO = L1.ARTICULO
        ORDER BY FECHA DESC
     ) DOC
    ,(SELECT TOP 1
          CANTIDAD
        FROM Lineas
        WHERE ARTICULO = L1.ARTICULO
        ORDER BY FECHA DESC
     ) CANT
  FROM Lineas AS L1
  WHERE L1.CODCLIENTE = 5195
  GROUP BY L1.ARTICULO, L1.DESCRIPCION, L1.CODCLIENTE
Un saludo

P.D.: Esta vez sí, esto es SQL SERVER en el firebird tendrá que cambir el TOP por no se cual

marcial 09-12-2012 12:21:25

1 Archivos Adjunto(s)
Hola a todos:
Olbeup, muchas gracias por tu código. La sentencia equivalente a TOP es FIRST. Aparte de eso, he tenido que hacerle alguna pequeña modificación para que el resultado fuera el deseado (según se ve en el ejemplo que adjunto ya que no asociaba bien el cliente con las lineas).

Creo que el código, por si a alguien le hace falta en el futuro sería este:

Código Delphi [-]
 SQL1 := 'SELECT  L1.ARTICULO ,L1.DESCRIPCION ,L1.CODCLIENTE ,(SELECT MAX(FECHA) FROM Lineas WHERE ARTICULO = L1.ARTICULO AND CODCLIENTE = L1.CODCLIENTE) FECHA, ' +
         '(SELECT FIRST 1 SERIE FROM Lineas WHERE ARTICULO = L1.ARTICULO and CODCLIENTE = ''' + Edit4.Text + ''' ORDER BY FECHA DESC) SERIE, ' +
         '(SELECT FIRST 1 PRECIOVENTA FROM Lineas WHERE ARTICULO = L1.ARTICULO and CODCLIENTE = ''' + Edit4.Text + ''' ORDER BY FECHA DESC) PRECIOVENTA, ' +
         '(SELECT FIRST 1 HORAGRABACION FROM Lineas WHERE ARTICULO = L1.ARTICULO and CODCLIENTE = ''' + Edit4.Text + ''' ORDER BY FECHA DESC) HORAGRABACION, ' +
         '(SELECT FIRST 1 DOCUMENTO FROM Lineas WHERE ARTICULO = L1.ARTICULO and CODCLIENTE = ''' + Edit4.Text + ''' ORDER BY FECHA DESC) DOCUMENTO, ' +
         '(SELECT FIRST 1 CANTIDAD  FROM Lineas WHERE ARTICULO = L1.ARTICULO and CODCLIENTE = ''' + Edit4.Text + ''' ORDER BY FECHA DESC) CANTIDAD ' +
         '  FROM Lineas AS L1 ' +
         '  WHERE L1.CODCLIENTE = ''' + Edit4.Text + ''' GROUP BY L1.ARTICULO, L1.DESCRIPCION, L1.CODCLIENTE';

if pFIBTransaction1.InTransaction then pFIBTransaction1.CommitRetaining;
pFIBTransaction1.StartTransaction;
LINEAS.Close;
LINEAS.SelectSQL.Clear;
LINEAS.SelectSQL.Add(SQL1);
LINEAS.QSelect.ExecQuery;
pFIBtransaction1.CommitRetaining;
LINEAS.Open;

Por tanto, si es que no me corregis, doy el tema a solucionado gracias a todas las aportaciones recibidas. Todas han sido muy importantes de una u otra manera, pero especialmente la de Olbeup.

Muchas gracias.


La franja horaria es GMT +2. Ahora son las 08:53:23.

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