none
ORDENAR REGISTROS SEGUN CRITERIO Y ACTUALIZAR SEGUN CRITERIO RRS feed

  • Pregunta

  • Buenas noches, tengo una tabla que contiene ciertos registros como en la imagen 01, ello consta de 4 columnas, la columna PACK, es una columna que esta formada con numero 1 y 2, eso quiere decir que el numero 1 y 2 forman un PACK

    La idea de todo ello es que el query debe tener los siguientes criterios debe ordenar por el precio de mayor a menor y como también debe comenzar actualizar siempre y cuando los códigos formen un pack, actualizar la columna elegir con valores numérico que comienzan con 1, por ejemplo los 2 primeros códigos forman un pack y la columna elegir se actualizo con valor 1, luego los otros 2 códigos también forman un pack y actualizo la columna con valor 2, los 2 últimos códigos no se actualizaron porque no conforman ningún pack, espero me puedan ayudar muchas gracias



    lunes, 24 de julio de 2017 0:40

Respuestas

  • Intenta con la siguiente consulta:

    DECLARE @NombreTabla table (CODIGO varchar(10), PACK int, PRECIO decimal(9,2), ELEGIR int);
    INSERT INTO @NombreTabla VALUES 
        ('14.0', 1, 45, NULL),
        ('50.0', 2, 25, NULL),
        ('17.9', 2, 23, NULL),
        ('89.0', 1, 75, NULL),
        ('101.0', 2, 64, NULL),    
        ('239.0', NULL, 56, NULL);    
    
    WITH T AS
    (
        SELECT t1.PRECIO, t1.ELEGIR, SUM(t1.PACK % 2) OVER(ORDER BY t1.PRECIO DESC) G
        FROM @NombreTabla t1
    ),
    R AS
    (
        SELECT 
    	   t1.ELEGIR, t1.G, ROW_NUMBER() OVER(PARTITION BY t1.G ORDER BY t1.PRECIO DESC) R,
    	   COUNT(*) OVER(PARTITION BY t1.G) C
        FROM T t1
    )
    UPDATE R
    SET 
        ELEGIR = CASE WHEN C >=2 AND R IN (1, 2) THEN G ELSE NULL END;
    
    --Mostrar resultados
    SELECT t1.* FROM @NombreTabla t1
    ORDER BY CASE WHEN t1.PACK IS NULL THEN 1 ELSE 0 END, t1.PRECIO DESC;
    GO


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    lunes, 24 de julio de 2017 3:00

Todas las respuestas

  • Intenta con la siguiente consulta:

    DECLARE @NombreTabla table (CODIGO varchar(10), PACK int, PRECIO decimal(9,2), ELEGIR int);
    INSERT INTO @NombreTabla VALUES 
        ('14.0', 1, 45, NULL),
        ('50.0', 2, 25, NULL),
        ('17.9', 2, 23, NULL),
        ('89.0', 1, 75, NULL),
        ('101.0', 2, 64, NULL),    
        ('239.0', NULL, 56, NULL);    
    
    WITH T AS
    (
        SELECT t1.PRECIO, t1.ELEGIR, SUM(t1.PACK % 2) OVER(ORDER BY t1.PRECIO DESC) G
        FROM @NombreTabla t1
    ),
    R AS
    (
        SELECT 
    	   t1.ELEGIR, t1.G, ROW_NUMBER() OVER(PARTITION BY t1.G ORDER BY t1.PRECIO DESC) R,
    	   COUNT(*) OVER(PARTITION BY t1.G) C
        FROM T t1
    )
    UPDATE R
    SET 
        ELEGIR = CASE WHEN C >=2 AND R IN (1, 2) THEN G ELSE NULL END;
    
    --Mostrar resultados
    SELECT t1.* FROM @NombreTabla t1
    ORDER BY CASE WHEN t1.PACK IS NULL THEN 1 ELSE 0 END, t1.PRECIO DESC;
    GO


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    lunes, 24 de julio de 2017 3:00
  • Gracias Williams, me ayudo mucho 
    lunes, 24 de julio de 2017 3:37
  • Interesante problema.

    No se si este ejemplo es posible en tu data pero el codigo marcado como respuesta no da el resultado esperado.

    Trata insertando esta fila ('11.0', 1, 110, NULL). El resultado es:

    /*
    
    CODIGO	PACK	PRECIO	ELEGIR
    11.0	1	110.00	NULL
    89.0	1	75.00	2
    101.0	2	64.00	2
    14.0	1	45.00	3
    50.0	2	25.00	3
    17.9	2	23.00	NULL
    239.0	NULL	56.00	NULL
    
    */

    Lo primero que se me ocurre es buscar un identificador de grupo.  Si dos filas estan consecutivas y estas son PACK = 1 y PACK = 2 entonces si enumeramos las filas por PRECIO de forma descendiente, entonces la enumeracion menos el valor de PACK pareceria ser un buen identificador.

    Una vez que tenemos los grupos, cualculamos el numero de filas por cada grupo, el minimo y maximo valor de PACK en el grupo y procedemos a filtrar solo aquellos grupo con dos cuyo minimo es 1 y maximo es 2. Ahora enumeramos usando DENSE_RANK y ese seria el valor de ELEGIR.

    DECLARE @NombreTabla table (CODIGO varchar(10), PACK int, PRECIO decimal(9,2), ELEGIR int);
    INSERT INTO @NombreTabla VALUES 
    	('11.0', 1, 110, NULL),
    
        ('14.0', 1, 45, NULL),
        ('50.0', 2, 25, NULL),
        ('17.9', 2, 23, NULL),
        ('89.0', 1, 75, NULL),
        ('101.0', 2, 64, NULL),    
        ('239.0', NULL, 56, NULL);
    
    WITH R1 AS (
    SELECT
        PACK,
        ELEGIR,
        ROW_NUMBER() OVER(ORDER BY PRECIO DESC) - PACK AS grp
    FROM
        @NombreTabla
    )
    , R2 AS (
    SELECT
        R1.PACK,
        R1.ELEGIR,
        R1.grp,
        COUNT(*) OVER(PARTITION BY grp) AS cnt,
        MIN(R1.PACK) OVER(PARTITION BY R1.grp) AS min_pack,
        MAX(R1.PACK) OVER(PARTITION BY R1.grp) AS max_pack
    FROM
        R1
    WHERE
        grp IS NOT NULL
    )
    , R3 AS (
    SELECT
        R2.PACK,
        R2.ELEGIR,
        R2.grp,
        R2.cnt,
        R2.min_pack,
        R2.max_pack,
        DENSE_RANK() OVER(ORDER BY grp) AS _Elegir
    FROM
        R2
    WHERE
        cnt = 2
        AND R2.min_pack = 1
        AND R2.max_pack = 2
    )
    UPDATE R3
    SET R3.ELEGIR = R3._Elegir;
    
    SELECT
    	*
    FROM
    	@NombreTabla
    ORDER BY
    	PRECIO DESC;
    GO
    
    /*
    
    CODIGO	PACK	PRECIO	ELEGIR
    11.0	1	110.00	NULL
    89.0	1	75.00	1
    101.0	2	64.00	1
    239.0	NULL	56.00	NULL
    14.0	1	45.00	2
    50.0	2	25.00	2
    17.9	2	23.00	NULL
    
    */


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    lunes, 24 de julio de 2017 16:11