none
Distribución de Registros con Cantidades RRS feed

  • Pregunta

  • Hola Colegas, es la primera vez que escribo aquí, tengo la siguiente duda y estoy buscando apoyo.

    Tengo un listado de clientes que son morosos y algunos tienen más de una factura vencida, entonces se listado de cliente se requiere distribuir entre los ejecutivos de cobranza para que les llamen, la distribución debe de estar distribuida (valga la redundancia) por monto.

    Tengo los Ejecutivos y Clientes, como verán algunos tienen varios documentos, estos clientes deberán ser distribuidos entre estos ejecutivos de cobranza:


    Reglas:

    Que el Monto sea los mas parecido entre los Ejecutivos.

    Si a Samuel le toco el Cliente 1 que todos los Documentos sean para Samuel, lo que se desea obtener es algo así:


    Que el resultado me indique cuales clientes le tomaron a cual ejecutivo, y que los montos sean lo mas parecido posibles.

    He usado varios scripts pero no me sale, y tengo un While que me funciona pero tarda demasiado y que son muchos registros, ojala alguien tenga alguna idea.

    De antemano muchas gracias.


    • Editado mvazquez jueves, 18 de junio de 2015 20:25
    jueves, 18 de junio de 2015 20:24

Respuestas

  • Que tal,

    Yo lo haría algo así:

    DECLARE @TablaEjecutivo table
    (
    	ID int,
    	Nombre varchar(10)
    );
    
    declare @TablaCliente table
    (
    	Cliente int,
    	Documento varchar(40),
    	Monto numeric(18,7)
    );
    
    declare @TablaClienteTempo table
    (
    	Cliente int,
    	Documento varchar(40),
    	Monto numeric(18,7)
    );
    
    insert into @TablaEjecutivo
    select 1, 'P' union all
    select 2, 'S' union all
    select 3, 'E' 
    
    insert into @TablaCliente
    select 1, '106',5600 union all
    select 1, '107',21600 union all
    select 1, '108',15980 union all
    select 1, '109',25000 union all
    select 2, '109',2911 union all
    select 2, '109',2730 union all
    select 3, '109',3000 
    
     
    DECLARE @cantEjecutivo smallint;
    DECLARE @Promediocobrar int; --no importa los decimales
    
    SELECT 
    	@cantEjecutivo = count(ID) 
    FROM @TablaEjecutivo;
    
    
    insert into @TablaClienteTempo(Cliente, Monto)
    SELECT Cliente, AVG(Monto) As Monto
    FROM @TablaCliente
    Group By Cliente 
    
    select @Promediocobrar = AVG(Monto)
    FROM @TablaClienteTempo;
    
    select @cantEjecutivo;
    --asegurar que el ID Ejecutivo sea incremental y de uno a uno
    select @Promediocobrar;
    
    DECLARE Cliente_cursor CURSOR FOR
    SELECT 
    	Cliente, Documento, Monto
    FROM 
    	@TablaCliente;
    
    OPEN Cliente_cursor
    DECLARE @Cliente varchar(20)
    DECLARE @Documento varchar(40)
    declare @Monto numeric(18,7)
    declare @MontoPrueba numeric(18,7)
    declare @EjecutivoAsignado int
    declare @Iteracion int;
    set @Iteracion = 1;
    set @MontoPrueba = 0;
    
    
    declare @Resultado table
    (
    	Cliente varchar(20),
    	Documento varchar(40),
    	Monto numeric(18,7),
    	EjecutivoAsignado int
    );
    
    
    FETCH NEXT FROM Cliente_cursor INTO @Cliente,@Documento,@Monto
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
    
    	IF @Iteracion > @cantEjecutivo
    	BEGIN
    		SET @Iteracion = 1;
    	END
    
    	SET @MontoPrueba = @MontoPrueba + @Monto;
    		
    	INSERT @Resultado(Cliente, Documento, Monto, EjecutivoAsignado) 
    	SELECT @Cliente, @Documento, @Monto, @Iteracion
    
    	IF @MontoPrueba > @Promediocobrar
    	BEGIN
    		SET @Iteracion = @Iteracion + 1;
    	END
    
    	FETCH NEXT FROM Cliente_cursor INTO @Cliente,@Documento,@Monto
    
    END
    
    CLOSE Cliente_cursor
    DEALLOCATE Cliente_cursor
    
    SELECT * FROM @Resultado;
    

    Saludos,


    Ayacucho - Perú
    Recuerda si mi solución atiende tu consulta por favor márcala como útil y como respuesta.

    http://litigiouslobo.blogspot.com/
    El Blog de Herbert Mendoza

    lunes, 22 de junio de 2015 19:31

Todas las respuestas

  • Wow al parecer nadie me puede apoyar...
    lunes, 22 de junio de 2015 16:03
  • Que tal,

    Lo he leído y queda algunas dudas, por favor podrías indicar que lógica se debe de usar para asociar un Ejecutivo y un Cliente, como se calcula el monto máximo a ser asignado a un ejecutivo.

    Saludos,


    Ayacucho - Perú
    Recuerda si mi solución atiende tu consulta por favor márcala como útil y como respuesta.

    http://litigiouslobo.blogspot.com/
    El Blog de Herbert Mendoza

    lunes, 22 de junio de 2015 16:09
  • Gracias SteveMorrison

    Te comento, espero darme a entender.

    Cada Documento (Factura) de un cliente tiene un monto, es decir, es una Factura por X cantidad, entonces, el Cliente debe esa Cantidad y ese es el Monto a Recuperar, es decir, es lo que se le cobrara al Cliente, los Ejecutivos le llamaran a los Clientes que les asignemos para Cobrarles la Cantidad de la Factura (Monto a Recuperar)

    Si lo veo desde un ciclo, seria, recorrer cada registro y asignarle una a cada Ejecutivo, no existe relación entre Cliente y Ejecutivo, justamente eso es lo que se busca.

    El objetivo es, asignarle N clientes cada ejecutivo procurando que la suma del Monto a Recuperar sea mas o menos la misma para cada ejecutivo.

    Lo que me gustaría es NO usar un ciclo, ver si existe alguna otra manera de hacerlo para que no sea lento.

    No se si con esta información haya aclarado tu duda, de lo contrario por favor coméntame

    De antemano muchas gracias.

    lunes, 22 de junio de 2015 18:06
  • Si solo quieres dividir las filas en N cantidad de grupos de manera equitativa y sin ningún patrón ni relación en específico ( que fue lo que yo entendí ) , existe la función NTILE que te pueda ayudar en esto, en la liga hay claros ejemplos de como resolverlo así y tengo una publicación en mi blog, el cual ahorita no puedo entrar porque el proxy en mi trabajo me lo impde, pero creo que de esta manera puedes resolver lo que buscas.

    SALUDOS!


    SERGIO SANCHEZ ARIAS
    facebook twitter blogger google

    lunes, 22 de junio de 2015 19:09
  • Que tal,

    Yo lo haría algo así:

    DECLARE @TablaEjecutivo table
    (
    	ID int,
    	Nombre varchar(10)
    );
    
    declare @TablaCliente table
    (
    	Cliente int,
    	Documento varchar(40),
    	Monto numeric(18,7)
    );
    
    declare @TablaClienteTempo table
    (
    	Cliente int,
    	Documento varchar(40),
    	Monto numeric(18,7)
    );
    
    insert into @TablaEjecutivo
    select 1, 'P' union all
    select 2, 'S' union all
    select 3, 'E' 
    
    insert into @TablaCliente
    select 1, '106',5600 union all
    select 1, '107',21600 union all
    select 1, '108',15980 union all
    select 1, '109',25000 union all
    select 2, '109',2911 union all
    select 2, '109',2730 union all
    select 3, '109',3000 
    
     
    DECLARE @cantEjecutivo smallint;
    DECLARE @Promediocobrar int; --no importa los decimales
    
    SELECT 
    	@cantEjecutivo = count(ID) 
    FROM @TablaEjecutivo;
    
    
    insert into @TablaClienteTempo(Cliente, Monto)
    SELECT Cliente, AVG(Monto) As Monto
    FROM @TablaCliente
    Group By Cliente 
    
    select @Promediocobrar = AVG(Monto)
    FROM @TablaClienteTempo;
    
    select @cantEjecutivo;
    --asegurar que el ID Ejecutivo sea incremental y de uno a uno
    select @Promediocobrar;
    
    DECLARE Cliente_cursor CURSOR FOR
    SELECT 
    	Cliente, Documento, Monto
    FROM 
    	@TablaCliente;
    
    OPEN Cliente_cursor
    DECLARE @Cliente varchar(20)
    DECLARE @Documento varchar(40)
    declare @Monto numeric(18,7)
    declare @MontoPrueba numeric(18,7)
    declare @EjecutivoAsignado int
    declare @Iteracion int;
    set @Iteracion = 1;
    set @MontoPrueba = 0;
    
    
    declare @Resultado table
    (
    	Cliente varchar(20),
    	Documento varchar(40),
    	Monto numeric(18,7),
    	EjecutivoAsignado int
    );
    
    
    FETCH NEXT FROM Cliente_cursor INTO @Cliente,@Documento,@Monto
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
    
    	IF @Iteracion > @cantEjecutivo
    	BEGIN
    		SET @Iteracion = 1;
    	END
    
    	SET @MontoPrueba = @MontoPrueba + @Monto;
    		
    	INSERT @Resultado(Cliente, Documento, Monto, EjecutivoAsignado) 
    	SELECT @Cliente, @Documento, @Monto, @Iteracion
    
    	IF @MontoPrueba > @Promediocobrar
    	BEGIN
    		SET @Iteracion = @Iteracion + 1;
    	END
    
    	FETCH NEXT FROM Cliente_cursor INTO @Cliente,@Documento,@Monto
    
    END
    
    CLOSE Cliente_cursor
    DEALLOCATE Cliente_cursor
    
    SELECT * FROM @Resultado;
    

    Saludos,


    Ayacucho - Perú
    Recuerda si mi solución atiende tu consulta por favor márcala como útil y como respuesta.

    http://litigiouslobo.blogspot.com/
    El Blog de Herbert Mendoza

    lunes, 22 de junio de 2015 19:31