• Sábado 5 de Diciembre de 2020, 03:41

Autor Tema:  Consulta para obtener el pago mas retrasado  (Leído 2948 veces)

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Consulta para obtener el pago mas retrasado
« en: Jueves 7 de Noviembre de 2013, 01:38 »
0
Por lo regular yo soy el que da asistencia, pero ahora me toca que me den asistencia a mi XD.

Tengo la siguiente tabla en SQL Server:

Código: [Seleccionar]
create table creditos_abonos
(
contrato_id int not null,
semana int not null,
interes decimal (18,2) not null default 0,
abono decimal (18,2) not null default 0,
iva decimal (18,2) not null default 0,
fecha_pago datetime not null default getdate(),
pagado bit not null default 0,
)

Un ejemplo de los valores de la tabla:

contrato_id   semana   interes   abono   iva   fecha_pago   pagado
5   6   217.50   906.25   34.80   2013-04-30 00:00:00.000   1
5   7   217.50   906.25   34.80   2013-05-07 00:00:00.000   1
5   8   217.50   906.25   34.80   2013-05-14 00:00:00.000   0
5   9   217.50   906.25   34.80   2013-05-21 00:00:00.000   0
5   10   217.50   906.25   34.80   2013-05-28 00:00:00.000   0
9   9   67.50   281.25   10.80   2013-04-30 00:00:00.000   0
9   10   67.50   281.25   10.80   2013-05-07 00:00:00.000   0

Yo lo que quiero es una consulta que me de la semana mas atrasada en pago de todos los contratos, en este caso se considera pagada cuando el campo pago = 1 y no pagada cuando pago = 0

o sea en base a lo anterior necesito que me regrese lo siguiente

contrato_id   semana   interes   abono   iva   fecha_pago   pagado
5   8   217.50   906.25   34.80   2013-05-14 00:00:00.000   0
9   9   67.50   281.25   10.80   2013-04-30 00:00:00.000   0

Tengo la siguiente consulta
Código: [Seleccionar]
select
top 1
b.contrato_id, b.semana, b.interes, b.abono, b.iva, fecha_pago, pagado
from creditos_abonos as b
where pagado = 0
and fecha_pago < '24/08/2013'
and contrato_id = 5
order by contrato_id, semana;

El problema es que solo me regresa la semana mas atrasada de un solo contrato, en este caso el numero 5, y yo necesito la mas atrasada de todos los contratos de la tabla. Lo que he hecho es por medio de un ciclo dentro de un programa, revisar todas las filas de la tabla, cambiando el valor de la condicion contrato_id = 5, pero siento que es un metodo muy ineficiente. Si alguien tiene la manera de obtenerlo por medio de una sola consulta SQL me pareceria excelente.

Gracias de antemano =)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re:Consulta para obtener el pago mas retrasado
« Respuesta #1 en: Jueves 7 de Noviembre de 2013, 05:39 »
0
Bueno, yo mismo publicare la solucion, un amigo ya me ayudo con la solucion a mi problema, lo dejare publicado por si alguien llega a tener un problema parecido al mio sepa que hacer :)

Código: [Seleccionar]
select b.contrato_id, b.semana, b.interes, b.abono, b.iva, fecha_pago, pagado
from creditos_abonos b,
(SELECT MIN(c.semana) as semana, c.contrato_id as contrato_id
FROM creditos_abonos c
WHERE c.pagado =0
AND c.fecha_pago < '24/08/2013'
GROUP BY c.contrato_id)
as c where pagado = 0
and fecha_pago < '24/08/2013'
AND b.semana = c.semana
AND c.contrato_id = b.contrato_id
order by b.contrato_id, c.semana;

Igual si alguno tiene alguna otra forma de obtenerlo, no esta de mas.

Gracias a todos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

gabio2

  • Miembro MUY activo
  • ***
  • Mensajes: 402
  • Nacionalidad: mx
    • Ver Perfil
Re:Consulta para obtener el pago mas retrasado
« Respuesta #2 en: Jueves 7 de Noviembre de 2013, 17:11 »
0
Creo que te complicaste un poco, obtuve el mismo resultado con la siguiente sentencia:

Código: SQL
  1. SELECT b.contrato_id, b.semana, b.interes, b.abono, b.iva, b.fecha_pago, b.pagado
  2. FROM creditos_abonos b
  3. INNER JOIN
  4. (
  5. /*Aquí se hace la magia*/
  6. SELECT ca2.contrato_id,MIN(ca2.semana) AS Semana FROM creditos_abonos AS ca2
  7. WHERE ca2.pagado = 0 GROUP BY ca2.Contrato_id
  8. ) AS Prueba
  9. ON Prueba.contrato_id = b.contrato_id AND Prueba.Semana = b.semana
  10.  

Espero te sirva, Saludos!.
@gabio87

DiabloRojo

  • Miembro MUY activo
  • ***
  • Mensajes: 220
    • Ver Perfil
Re:Consulta para obtener el pago mas retrasado
« Respuesta #3 en: Viernes 8 de Noviembre de 2013, 03:42 »
0
Hola qué tal?

No servía hacer?:

Código: SQL
  1. SELECT contrato_id, MIN(semana) AS semana, interes, abono, iva, fecha_pago, pagado
  2.     FROM creditos_abonos
  3.     WHERE pagado = 0
  4.     GROUP BY contrato_id;
  5.  
« última modificación: Viernes 8 de Noviembre de 2013, 03:46 por DiabloRojo »

gabio2

  • Miembro MUY activo
  • ***
  • Mensajes: 402
  • Nacionalidad: mx
    • Ver Perfil
Re:Consulta para obtener el pago mas retrasado
« Respuesta #4 en: Viernes 8 de Noviembre de 2013, 04:03 »
0
Que tal saludos DiabloRojo.

Respondiendo tú pregunta, no, no sirve de tal manera como la pones debido a que el GROUP BY solo lo tiene contrato_id (para realizar eso es necesario agregar más campos al group by, pero entonces no regresara los datos que ProfesorX necesita), para agregar más campos es necesario usar alguna función como MAX, MIN, etc., en los campos que no estén dentro del GROUP BY.

Realice lo mismo que tú para llamar al contrado_id y semana, para hacer un inner join y poder obtener la información de los demás campos.

Saludos! :)

« última modificación: Viernes 8 de Noviembre de 2013, 04:06 por gabio2 »
@gabio87

DiabloRojo

  • Miembro MUY activo
  • ***
  • Mensajes: 220
    • Ver Perfil
Re:Consulta para obtener el pago mas retrasado
« Respuesta #5 en: Sábado 9 de Noviembre de 2013, 16:52 »
0
Qué tal gabio2,

Es decir, debo incluir en la cláusula GROUP BY cualquier campo que NO esté dentro de una función de agregado (min, max, sum...) y que aparezca después del SELECT.

Por otro lado, mi confusión parte de que hice la prueba en mysql y allí sí funciona  de la manera que sugerí :think:. pero revisando en sql server me doy cuenta de que funciona exactamente como tu propusiste.

Otra forma pudo haber sido (y esta vez sí en sql server):

Código: SQL
  1. SELECT contrato_id, semana, interes, abono, iva, fecha_pago, pagado
  2. FROM creditos_abonos ca1
  3. WHERE semana IN(SELECT MIN(semana) AS semana FROM creditos_abonos ca2 WHERE pagado = 0 AND ca1.contrato_id = ca2.contrato_id GROUP BY contrato_id);

Aunque creo que la manera más eficiente de realizar la consulta es la de gabio2.

Saludos

PS: Por cierto, recomiendo http://sqlfiddle.com/ para probar consultas contra mysql, postgre y sql server.
« última modificación: Sábado 9 de Noviembre de 2013, 16:56 por DiabloRojo »

gabio2

  • Miembro MUY activo
  • ***
  • Mensajes: 402
  • Nacionalidad: mx
    • Ver Perfil
Re:Consulta para obtener el pago mas retrasado
« Respuesta #6 en: Sábado 9 de Noviembre de 2013, 18:07 »
0
Muy buena tú observación DiabloRojo, de igual forma probé y efectivamente en MySQL no tuve problemas, un caso más para la araña....

Por cierto igual tú sentencia utilizando el IN en el WHERE, quedó bastante bien, intente probar la efectividad de ambas consultas midiendo el tiempo de respuesta, para ello ingrese 100 mil registros a la tabla, sin embargo ambas siguieron dando exactamente el mismo tiempo de respuesta y el mismo número de registros, por lo cuál puedo decir que ambas son igual de eficientes.

Saludos!
@gabio87