¿Existe una función Max en SQL Server que toma dos valores como Math.Max en .NET?
Quiero escribir una consulta como esta:
SELECT o.OrderId, MAX(o.NegotiatedPrice, o.SuggestedPrice)
FROM Order o
Pero no es así como MAX
funciona 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?
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:
- No requiere complicar su código con declaraciones UNION, PIVOT, UNPIVOT, UDF y CASE increíblemente largas.
- No está plagado del problema de manejar valores nulos, los maneja muy bien.
- Es fácil cambiar "MAX" por "MIN", "AVG" o "SUM". Puede utilizar cualquier función agregada para encontrar el agregado en muchas columnas diferentes.
- 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.
- 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)
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.
Necesitaría crear un User-Defined Function
si 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 CASE
declaración, como han dicho los demás?
Podría UDF
ser 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