Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 02-10-2017
identsoft identsoft is offline
Miembro
 
Registrado: abr 2006
Posts: 282
Poder: 18
identsoft Va por buen camino
¿se puede hacer esto en una instrucción sql?

Un saludo para todos.
necesito seleccionar una serie de registros con tres campos: NOMBRE, FECHA VENCIMIENTO, IMPORTE)de una tabla (firebird) que cumplan dos condiciones:
1.- que los registros seleccionados estén entre un rango de fechas (FECHA VENCIMIENTO, es fácil)
2.- que la suma del campo IMPORTE de los registros seleccionados, no supere un importe determinado (vendrá de un tedit).

¿Es posible hacerlo con una instrucción sql o tendré que recorrer la tabla?
Estoy utilizando firebird y dbexpres.
Gracias por adelantado.
Responder Con Cita
  #2  
Antiguo 02-10-2017
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Claro, para filtrar un agregado como SUM utiliza la clausula HAVING:

https://www.w3schools.com/sql/sql_having.asp
__________________
El malabarista.
Responder Con Cita
  #3  
Antiguo 02-10-2017
identsoft identsoft is offline
Miembro
 
Registrado: abr 2006
Posts: 282
Poder: 18
identsoft Va por buen camino
Y como seria? porque esto me da error:
Código SQL [-]
SELECT  NOMBRE, FECHAVTO,  IMPORTE 
FROM VTOSCOBR 
where FECHAVTO between '2017-04-28' and '2017-05-01' 
group by FECHAVTO 
having (sum(importe) < 1000)

Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause).

lo estoy probando con IBEXPERT antes de hacerlo con DELPHI
Responder Con Cita
  #4  
Antiguo 02-10-2017
Avatar de oscarac
[oscarac] oscarac is offline
Miembro Premium
 
Registrado: sep 2006
Ubicación: Lima - Perú
Posts: 2.009
Poder: 20
oscarac Va por buen camino
Código SQL [-]
SELECT  NOMBRE, FECHAVTO,  IMPORTE 
FROM VTOSCOBR 
where FECHAVTO between '2017-04-28' and '2017-05-01' 
group by FECHAVTO 
having (sum(importe) < 1000)


te falta agregar el campo Nombre en el group

Group by nombre, fechavto
__________________
Dulce Regalo que Satanas manda para mi.....
Responder Con Cita
  #5  
Antiguo 02-10-2017
nincillo nincillo is offline
Miembro
 
Registrado: may 2017
Posts: 151
Poder: 7
nincillo Va por buen camino
Cita:
Empezado por identsoft Ver Mensaje
Y como seria? porque esto me da error:
Código SQL [-]
SELECT  NOMBRE, FECHAVTO,  IMPORTE 
FROM VTOSCOBR 
where FECHAVTO between '2017-04-28' and '2017-05-01' 
group by FECHAVTO 
having (sum(importe) < 1000)

Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause).

lo estoy probando con IBEXPERT antes de hacerlo con DELPHI
¿Qué es lo que quieres que te salga como resultado del sql?

* ¿Una fila por cada uno de los recibos del cliente ?
* ¿Una única fila con la suma total de los recibos de cada cliente por día?


Porque dependiendo de lo que necesites realmente, el sql cambiará un poco.
Responder Con Cita
  #6  
Antiguo 02-10-2017
Avatar de oscarac
[oscarac] oscarac is offline
Miembro Premium
 
Registrado: sep 2006
Ubicación: Lima - Perú
Posts: 2.009
Poder: 20
oscarac Va por buen camino
Cita:
Empezado por nincillo Ver Mensaje
¿Qué es lo que quieres que te salga como resultado del sql?

* ¿Una fila por cada uno de los recibos del cliente ?
* ¿Una única fila con la suma total de los recibos de cada cliente por día?


Porque dependiendo de lo que necesites realmente, el sql cambiará un poco.
si, tiene toda la razon, si involucras la fecha de vencimiento en la consulta te saldran tantos registros como fechas existan
plantea mejor tu consulta, si puedes pon un ejemplo con datos y los resultados que buscas
__________________
Dulce Regalo que Satanas manda para mi.....
Responder Con Cita
  #7  
Antiguo 02-10-2017
identsoft identsoft is offline
Miembro
 
Registrado: abr 2006
Posts: 282
Poder: 18
identsoft Va por buen camino
Efectivamente, quiero que me salga una linea (registro) por cada fecha de vencimiento (con su nombre, su fecha de vencimiento y su importe) pero hasta que la suma de los importes seleccionados sea menor o igual que una cantidad determinada (en delphi vendrá de un tedit).

ejemplo: Suma de importes : 100€

CLIENTE FECHA IMPORTE
cliente 1 21-09-2017 40
cliente 2 22-09-2017 30
cliente 3 23-09-2017 20

cliente 4 23-09-2017 30
cliente 5 23-09-2017 20

El sql debe seleccionar cliente1,cliente2 y cliente3, porque si seleccionamos cliente 4, ya sobrepasamos el importe máximo que tenemos que seleccionar

Perdón si no he sabido expresarme mejor. Y sobretodo gracias por vuestro tiempo.
Responder Con Cita
  #8  
Antiguo 02-10-2017
Avatar de oscarac
[oscarac] oscarac is offline
Miembro Premium
 
Registrado: sep 2006
Ubicación: Lima - Perú
Posts: 2.009
Poder: 20
oscarac Va por buen camino
Cliente 1, 2 y 3 es el mismo cliente?
__________________
Dulce Regalo que Satanas manda para mi.....
Responder Con Cita
  #9  
Antiguo 02-10-2017
identsoft identsoft is offline
Miembro
 
Registrado: abr 2006
Posts: 282
Poder: 18
identsoft Va por buen camino
Normalmente no, pero en algún caso excepcional pudiera darse el caso.
Responder Con Cita
  #10  
Antiguo 02-10-2017
Avatar de oscarac
[oscarac] oscarac is offline
Miembro Premium
 
Registrado: sep 2006
Ubicación: Lima - Perú
Posts: 2.009
Poder: 20
oscarac Va por buen camino
ah ya
entonces tu quieres una relacion de los n primeros clientes cuya suma de importes por fecha de vencimiento sea menor a X (tu edit)
__________________
Dulce Regalo que Satanas manda para mi.....
Responder Con Cita
  #11  
Antiguo 02-10-2017
identsoft identsoft is offline
Miembro
 
Registrado: abr 2006
Posts: 282
Poder: 18
identsoft Va por buen camino
Eso es lo que necesito.
Responder Con Cita
  #12  
Antiguo 02-10-2017
nincillo nincillo is offline
Miembro
 
Registrado: may 2017
Posts: 151
Poder: 7
nincillo Va por buen camino
Cita:
Empezado por identsoft Ver Mensaje
Eso es lo que necesito.
Entonces creo que lo que necesitas es algo así:

Código:
SELECT  NOMBRE, FECHAVTO,  SUM(IMPORTE) AS Total
FROM VTOSCOBR 
where FECHAVTO between '2017-04-28' and '2017-05-01' 
group by NOMBRE, FECHAVTO
having (sum(importe) < 1000)
--ORDER by LO QUE QUIERAS.....
Responder Con Cita
  #13  
Antiguo 02-10-2017
identsoft identsoft is offline
Miembro
 
Registrado: abr 2006
Posts: 282
Poder: 18
identsoft Va por buen camino
No es eso lo que busco.
Lo que intento sacar es todos los vencimientos comprendidos entre dos fecha (independientemente de si es el mismo cliente o es la misma fecha) pero (y aquí viene la cuestión) que la suma de lo que voy seleccionando( el importe total , no la suma del importe por cliente ) no supere el importe que le diga.

En forma de bucle seria:
leo registro 1 ; sumimporte = sumimporte + importe
si sumimporte > importeseleccionado salgo del bucle
si no
leo registro2 sumimporte = sumimporte + importe
si sumimporte > importeseleccionado salgo del bucle
sino
leo registro3......

algo así pero en forma de sql

gracias nincillo
Responder Con Cita
  #14  
Antiguo 02-10-2017
nincillo nincillo is offline
Miembro
 
Registrado: may 2017
Posts: 151
Poder: 7
nincillo Va por buen camino
Me temo que eso para un sql "normal" es bastante complicado.

Creo que tendrías que hacerlo utilizando algún cursor o algo así.
Responder Con Cita
  #15  
Antiguo 02-10-2017
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Es posible con Sql normal, pero todo depende del motor y su version. En el caso de Firebird, desde la version 3:

https://www.firebirdsql.org/file/com...3windowing.pdf
__________________
El malabarista.
Responder Con Cita
  #16  
Antiguo 02-10-2017
nincillo nincillo is offline
Miembro
 
Registrado: may 2017
Posts: 151
Poder: 7
nincillo Va por buen camino
Cita:
Empezado por mamcx Ver Mensaje
Es posible con Sql normal, pero todo depende del motor y su version. En el caso de Firebird, desde la version 3:

https://www.firebirdsql.org/file/com...3windowing.pdf
Menudo pedazo de manual interesante...
Pero no son horas para digerir algo tan "denso".

Me lo apunto para mañana, pero me implicaría cambiar a la versión 3, que hasta ahora no había pasado de la 2.5 por temor a incompatibilidades.
Responder Con Cita
  #17  
Antiguo 02-10-2017
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Pero las funciones windows LO VALEN. Son geniales y resuelven un montón de escenarios.

P.D: Y si uno tiene la opción, es bueno siempre ir actualizando el motor a lo ultimo. No solo porque por lo general mejoran desempeño y resuelven bugs, sino porque el SQL se ha ido actualizando!

A proposito, asi es como quedaria:

Código SQL [-]
-- Puse los datos en memoria pa testear
WITH datos AS (
SELECT 'cliente 1' as cliente, '21-09-2017' as fecha, 40 AS importe
UNION ALL
SELECT 'cliente 2', '22-09-2017', 30
UNION ALL
SELECT 'cliente 3', '23-09-2017', 20
UNION ALL
SELECT 'cliente 4', '23-09-2017', 30
UNION ALL
SELECT 'cliente 5', '23-09-2017', 20
)

SELECT * FROM (
   -- Aqui es la magia. Usando la funcion WINDOW SUM que recorre (como un FOR) ordenado por cliente. Es importante tener en cuenta el orden. Esto acumula la suma
    SELECT *, SUM(importe) OVER (ORDER BY cliente) AS acumulado FROM datos
) reporte
-- Y por ultimo se filtra
WHERE acumulado < 100
__________________
El malabarista.
Responder Con Cita
  #18  
Antiguo 02-10-2017
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por mamcx Ver Mensaje
Es posible con Sql normal, pero todo depende del motor y su version. En el caso de Firebird, desde la version 3:
https://www.firebirdsql.org/file/com...3windowing.pdf
Vaya, más cosas para estudiar
Responder Con Cita
  #19  
Antiguo 03-10-2017
identsoft identsoft is offline
Miembro
 
Registrado: abr 2006
Posts: 282
Poder: 18
identsoft Va por buen camino
Genial!!
El problema es que trabajo con firebird 2.5
Hay que estudiar la posibilidad del cambio.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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
Tu mac puede hacer esto????? AzidRain Humor 10 24-11-2010 01:16:25
Se puede hacer esto? Migpal OOP 3 22-10-2005 21:02:30
Se puede hacer esto ??????? AMINOA2R Firebird e Interbase 2 21-10-2005 18:50:59
Se puede hacer esto en POO? adlfv OOP 8 26-09-2005 17:28:55


La franja horaria es GMT +2. Ahora son las 19:26:50.


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