¿Existe una función Max en SQL Server que toma dos valores como Math.Max ​​en .NET?

Resuelto skb asked hace 16 años • 31 respuestas

Quiero escribir una consulta como esta:

SELECT o.OrderId, MAX(o.NegotiatedPrice, o.SuggestedPrice)
FROM Order o

Pero no es así como MAXfunciona la función, ¿verdad? Es una función agregada, por lo que espera un único parámetro y luego devuelve el MAX de todas las filas.

¿Alguien sabe cómo hacerlo a mi manera?

skb avatar Sep 24 '08 05:09 skb
Aceptado

Si está utilizando SQL Server 2008 (o superior), esta es la mejor solución:

SELECT o.OrderId,
       (SELECT MAX(Price)
        FROM (VALUES (o.NegotiatedPrice),(o.SuggestedPrice)) AS AllPrices(Price))
FROM Order o

Todo el crédito y los votos deben ir a la respuesta de Sven a una pregunta relacionada, "¿SQL MAX de varias columnas?"
Digo que es la " mejor respuesta " porque:

  1. No requiere complicar su código con declaraciones UNION, PIVOT, UNPIVOT, UDF y CASE increíblemente largas.
  2. No está plagado del problema de manejar valores nulos, los maneja muy bien.
  3. Es fácil cambiar "MAX" por "MIN", "AVG" o "SUM". Puede utilizar cualquier función agregada para encontrar el agregado en muchas columnas diferentes.
  4. No está limitado a los nombres que utilicé (es decir, "Todos los precios" y "Precio"). Puedes elegir tus propios nombres para que sea más fácil de leer y comprender para el próximo chico.
  5. Puede encontrar múltiples agregados utilizando tablas_derivadas de SQL Server 2008 de la siguiente manera:
    SELECT MAX(a), MAX(b) FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10) ) AS MiTabla(a, b)
MikeTeeVee avatar Feb 25 '2012 23:02 MikeTeeVee

Se puede hacer en una línea:

-- the following expression calculates ==> max(@val1, @val2)
SELECT 0.5 * ((@val1 + @val2) + ABS(@val1 - @val2)) 

Editar: si trabaja con números muy grandes, tendrá que convertir las variables de valor a bigint para evitar un desbordamiento de enteros.

splattne avatar Nov 16 '2008 11:11 splattne

Necesitaría crear un User-Defined Functionsi quisiera tener una sintaxis similar a la de su ejemplo, pero ¿podría hacer lo que quiere, en línea, con bastante facilidad con una CASEdeclaración, como han dicho los demás?

Podría UDFser algo como esto:

create function dbo.InlineMax(@val1 int, @val2 int)
returns int
as
begin
  if @val1 > @val2
    return @val1
  return isnull(@val2,@val1)
end

...y lo llamarías así...

SELECT o.OrderId, dbo.InlineMax(o.NegotiatedPrice, o.SuggestedPrice) 
FROM Order o
Kevin avatar Sep 23 '2008 23:09 Kevin