none
Obtener registro en base a valor mínimo RRS feed

  • Pregunta

  • Hola,

    Tengo la siguiente tabla y sus valores

    ESCALA DESCRIPCIÓN PORCENTAJE MÍNIMO
    A ÓPTIMO   80
    B ADECUADO 
      65
    C PROMEDIO   50
    D NECESITA MEJORAR   24

    Quiero realizar una consulta de tal forma que le proporcione un porcentaje y me devuelva en qué escala se encuentra. Por ejemplo, si le proporciono 26 me debe devolver el registro de la Escala C

    Le estoy dando vueltas y no lo consigo:


    • Editado eduar2083 viernes, 21 de febrero de 2020 16:49
    viernes, 21 de febrero de 2020 16:48

Respuestas

  • Hola eduar2083:

    Una de las múltiples soluciones, puede ser tal que:

    declare @t table
    ([Escala]      varchar,
     [Descripcion] varchar(20),
     [Porcentaje]  tinyint
    );
    insert into @t(Escala, Descripcion, Porcentaje)
    values('A', 'ÓPTIMO', 80), ('B', 'ADECUADO', 65), ('C', 'PROMEDIO', 50), ('D', 'NECESITA MEJORAR', 24);

    Declare @value tinyInt= 26;
    With R
        as (    
            Select t.Escala
                 , t.Descripcion
                 , t.Porcentaje
                 , case when t.Porcentaje >@value then 1
                        else 0 end rango
                 from @t t)
        Select top(1)
         *
    from R
    where
    r.rango = 1
    order by porcentaje asc

    De los valore que contenga la tabla, los examinas con un case y marcas con un flag los que sean del tipo que esperas, y luego con el operador top, obtienes el primero que encaje en ese rango.

    Salida

    Tablas de expresión común

    https://javifer2.wordpress.com/2018/12/18/with-cte-tablas-de-expresion-comun-1/


    viernes, 21 de febrero de 2020 18:16

Todas las respuestas

  • Hola eduar2083:

    Una de las múltiples soluciones, puede ser tal que:

    declare @t table
    ([Escala]      varchar,
     [Descripcion] varchar(20),
     [Porcentaje]  tinyint
    );
    insert into @t(Escala, Descripcion, Porcentaje)
    values('A', 'ÓPTIMO', 80), ('B', 'ADECUADO', 65), ('C', 'PROMEDIO', 50), ('D', 'NECESITA MEJORAR', 24);

    Declare @value tinyInt= 26;
    With R
        as (    
            Select t.Escala
                 , t.Descripcion
                 , t.Porcentaje
                 , case when t.Porcentaje >@value then 1
                        else 0 end rango
                 from @t t)
        Select top(1)
         *
    from R
    where
    r.rango = 1
    order by porcentaje asc

    De los valore que contenga la tabla, los examinas con un case y marcas con un flag los que sean del tipo que esperas, y luego con el operador top, obtienes el primero que encaje en ese rango.

    Salida

    Tablas de expresión común

    https://javifer2.wordpress.com/2018/12/18/with-cte-tablas-de-expresion-comun-1/


    viernes, 21 de febrero de 2020 18:16
  • Hola Javi

    Estuve tratando de resolver este "acertijo", pero nada, veo que has publicado una solucion, solo que si yo le doy copy-paste (qepd el inventor de esta formula), me da otro resultado.

    Segun yo, deberia resolverse tambien de esta forma:

    SELECT TOP 1 ESCALA, DESCRIPCION, [PORCENTAJE_MINIMO]FROM @Mytable

    --WHERE [PORCENTAJE_MINIMO] < @Myparametro

    ORDER BY ABS([PORCENTAJE_MINIMO] - @Myparametro) AS

    Pero me da el mismo resultado: 24, debiendo ser 50

    Lo estoy probando en una version SQL Server 2012


    IIslas Master Consultant SQL Server


    viernes, 21 de febrero de 2020 19:29
  • Hola iislas:

    No tiene que ver la versión para esto.

    Tiene que ver con el copy-paste por mi parte.

    declare @t table
    ([Escala]      varchar, 
     [Descripcion] varchar(20), 
     [Porcentaje]  tinyint
    );
    insert into @t(Escala, Descripcion, Porcentaje)
    values('A', 'ÓPTIMO', 80), ('B', 'ADECUADO', 65), ('C', 'PROMEDIO', 50), ('D', 'NECESITA MEJORAR', 24);
    
    Declare @value tinyInt= 26;
    With R
    	as (	
    		Select t.Escala
    			 , t.Descripcion
    			 , t.Porcentaje
    			 , case when t.Porcentaje >@value then 1 
    					else 0 end rango 
    			 from @t t)
    	Select --top(1)
    	 * 
    from R 
    --where 
    --r.rango = 1
    --order by porcentaje asc
    

    Fíjate que he cambiado el < por > que es indiferente, porque solo hay que cambiar el where.... pero así vale

    Observa que he comentado las lineas del where y el top para ver todos los resultados.

    Es claro con los resultados, que solo hay que obtener el primer resultado de rango 1 pero ordenado por porcentaje.

    declare @t table
    ([Escala]      varchar, 
     [Descripcion] varchar(20), 
     [Porcentaje]  tinyint
    );
    insert into @t(Escala, Descripcion, Porcentaje)
    values('A', 'ÓPTIMO', 80), ('B', 'ADECUADO', 65), ('C', 'PROMEDIO', 50), ('D', 'NECESITA MEJORAR', 24);
    
    Declare @value tinyInt= 26;
    With R
    	as (	
    		Select t.Escala
    			 , t.Descripcion
    			 , t.Porcentaje
    			 , case when t.Porcentaje >@value then 1 
    					else 0 end rango 
    			 from @t t)
    	Select top(1)
    	 * 
    from R 
    where 
    r.rango = 1
    order by porcentaje asc
    

    El error fue mío cuando formateaba el código.

    Tu solución es casi.

    SELECT TOP 1 ESCALA, DESCRIPCION, Porcentaje FROM @t
    
    WHERE [PORCENTAJE] > @value
    
    ORDER BY [PORCENTAJE] 

    Simplemente porcentaje tiene que ser mayor que parámetro y entonces de estos valores obtienes el primero.

    No te hace falta restar en el order by.

    Es realmente la misma solución usando ctes, o usando la select directa.

    viernes, 21 de febrero de 2020 19:43
  • En verdad que estuve muy cerca, gracias por entercambio de conocimientos, aunque no es mi ramo el T-SQL, me divierte tanto resolver problemas, como un juego de ajedrez.  Saludos Javi

    IIslas Master Consultant SQL Server

    viernes, 21 de febrero de 2020 21:27
  • De nada. Un placer. Nos vemos en el próximo hilo....
    sábado, 22 de febrero de 2020 6:03