2011-01-18 14 views
12

Quiero encontrar el valor máximo de varias columnas.¿Función en SQL Server 2008 similar a GREATEST en mysql?

MySQL soporta la función GREATEST pero SQL Server no lo hace.

¿Existe alguna función similar a esta en SQL Server 2008?

+0

favor también un vistazo a http: // dba. stackexchange.com/questions/21542/what-is-the-most-efficient-way-to-get-the-minimum-of-multiple-columns-on-sql-ser –

Respuesta

1

Puede utilizar MAX en una sub-consulta

+3

Así que muestre t el público _how_. – SQB

20

No. Pero una consulta secundaria puede acceder a las columnas de la consulta externa para que pueda agregar una consulta secundaria UNION ALL ing las columnas de interés como tabla derivada y luego seleccionar max de esa.

SELECT *, 
     (SELECT MAX(c) FROM 
        (SELECT number AS c 
        UNION ALL 
        SELECT status) T) AS GreatestNumberOrStatus 
FROM master..spt_values 

O una versión ligeramente más concisa ya que estás en 2008.

SELECT *, 
     (SELECT MAX(c) FROM (VALUES(number),(status)) T (c)) AS Greatest 
FROM master..spt_values 
+2

+1, aunque es menos eficiente que un grupo de sentencias 'CASE'. – Quassnoi

+0

De acuerdo, pero no es catastróficamente ineficiente y más fácil de mantener si el número de columnas es grande. –

+0

"puede agregar una subconsulta UNION TODAS las columnas de interés como una tabla derivada" - podría hacer lo mismo con un CTE. – onedaywhen

5

Para ello, he creado una función escalar de la siguiente manera:

CREATE FUNCTION [dbo].[MaxOrNull](@val1 int, @val2 int) 
returns int 
as 
begin 
    if @val1 >= @val2 RETURN @val1 
    if @val1 < @val2 RETURN @val2 

    RETURN NULL 
end 

Es la solución más elegante y se puede usar en cualquier parte de tu código SQL.

+0

¡No estoy seguro de haber visto alguna vez la función escalar de palabras y elegante en la misma oración anterior! ¿Cómo usaría el OP esto para calcular 'GREATEST (col1, col2, col3, col4, col5, col6)' por ejemplo? ¿No necesitaría muchas permutaciones? Editar: En realidad, puede anidar las llamadas por supuesto en este caso donde las permutaciones crecen es el escenario diferente en el que desea ordenar entre columnas. –

+0

Bueno, @Martin, a veces se necesita un cambio de punto de vista para ver la elegancia. La codificación difícil de SQL sucio por todo el lugar como la respuesta detallada en la respuesta superior ^^^ de arriba es simplemente una locura. Usted respondió su segunda pregunta. Lo mismo sería válido en C++ o C#. – IamIC

+2

Un tramo para mí para darte +1. Pero este es el enfoque que he utilizado antes de SQL 2008, en lugar de preferencia sobre select-max-union anidada. La función que normalmente uso es más concisa 'create function dbo.greater (@a int, @b int) devuelve int como begin return case cuando @a> = isnull (@ b, @ a) then @a else @b end end ' – RichardTheKiwi

2

Yo recomendaría el siguiente solución:

SELECT (CASE WHEN t.createdt < t.changedt THEN t.changedt ELSE t.created END) AS ChgDate 
    FROM table t 
1

Una posible solución:

Create FUNCTION [dbo].[MaxOf] 
    (
     @val1 INT =0, 
     @val2 INT=0 , 
     @val3 INT =0, 
     @val4 INT =0, 
     @val5 INT =0, 
     @val6 INT =0, 
     @val7 INT =0, 
     @val8 INT =0, 
     @val9 INT =0, 
     @val10 INT =0, 
     @val11 INT =0, 
     @val12 INT =0, 
     @val13 INT =0, 
     @val14 INT =0, 
     @val15 INT =0, 
     @val16 INT =0, 
     @val17 INT =0, 
     @val18 INT =0, 
     @val19 INT =0, 
     @val20 INT =0) 
     --OUTPUT 
    RETURNS INT WITH SCHEMABINDING 
AS 
    BEGIN 
     DECLARE @MAX AS INT ; 
     SET @MAX=0 
     IF isnull(@val1,0)> isnull(@MAX,0) SET @MAX=isnull(@val1,0) 
     IF isnull(@val2,0)> isnull(@MAX,0) SET @MAX=isnull(@val2,0) 
     IF isnull(@val3,0)> isnull(@MAX,0) SET @MAX=isnull(@val3,0) 
     IF isnull(@val4,0)> isnull(@MAX,0) SET @MAX=isnull(@val4,0) 
     IF isnull(@val5,0)> isnull(@MAX,0) SET @MAX=isnull(@val5,0) 
     IF isnull(@val6,0)> isnull(@MAX,0) SET @MAX=isnull(@val6,0) 
     IF isnull(@val7,0)> isnull(@MAX,0) SET @MAX=isnull(@val7,0) 
     IF isnull(@val8,0)> isnull(@MAX,0) SET @MAX=isnull(@val8,0) 
     IF isnull(@val9,0)> isnull(@MAX,0) SET @MAX=isnull(@val9,0) 
     IF isnull(@val10,0)> isnull(@MAX,0) SET @MAX=isnull(@val10,0) 
     IF isnull(@val11,0)> isnull(@MAX,0) SET @MAX=isnull(@val11,0) 
     IF isnull(@val12,0)> isnull(@MAX,0) SET @MAX=isnull(@val12,0) 
     IF isnull(@val13,0)> isnull(@MAX,0) SET @MAX=isnull(@val13,0) 
     IF isnull(@val14,0)> isnull(@MAX,0) SET @MAX=isnull(@val14,0) 
     IF isnull(@val15,0)> isnull(@MAX,0) SET @MAX=isnull(@val15,0) 
     IF isnull(@val16,0)> isnull(@MAX,0) SET @MAX=isnull(@val16,0) 
     IF isnull(@val17,0)> isnull(@MAX,0) SET @MAX=isnull(@val17,0) 
     IF isnull(@val18,0)> isnull(@MAX,0) SET @MAX=isnull(@val18,0) 
     IF isnull(@val19,0)> isnull(@MAX,0) SET @MAX=isnull(@val19,0) 
     IF isnull(@val20,0)> isnull(@MAX,0) SET @MAX=isnull(@val20,0) 

     RETURN @MAX ; 
    END 

y la llamada sería

SELECT dbo.MaxOf (2,3,4,0,0,0,0,200,8,0,0,0,0,0,0,0,0,0,0,0) 
Cuestiones relacionadas