我想写一个这样的查询:
SELECT o.OrderId, MAX(o.NegotiatedPrice, o.SuggestedPrice)
FROM Order o
但这不是MAX函数的工作原理,对吧?它是一个聚合函数,因此它需要一个参数,然后返回所有行的MAX。
有人知道我的方法吗?
我想写一个这样的查询:
SELECT o.OrderId, MAX(o.NegotiatedPrice, o.SuggestedPrice)
FROM Order o
但这不是MAX函数的工作原理,对吧?它是一个聚合函数,因此它需要一个参数,然后返回所有行的MAX。
有人知道我的方法吗?
当前回答
以下是一个带有NULL处理的IIF版本(基于Xin的回答):
IIF(a IS NULL OR b IS NULL, ISNULL(a,b), IIF(a > b, a, b))
逻辑如下,如果其中一个值为NULL,则返回非NULL的值(如果两个值都为NULL,则返回NULL)。否则返回较大的值。
MIN也是一样。
IIF(a IS NULL OR b IS NULL, ISNULL(a,b), IIF(a < b, a, b))
其他回答
对于上面关于大数字的答案,你可以在加减法之前做乘法。它有点笨重,但不需要石膏。(我不能说速度,但我认为它仍然非常快)
选择0.5*((@val1+@val2)+ ABS(@val1 - @val2)
更改
选择 @val1*0.5+@val2*0.5 + ABS(@val1*0.5 - @val2*0.5)
如果你想避免强制转换,至少有一个替代方案。
可以在一行中完成:
-- the following expression calculates ==> max(@val1, @val2)
SELECT 0.5 * ((@val1 + @val2) + ABS(@val1 - @val2))
编辑:如果处理的是非常大的数字,则必须将值变量转换为bigint,以避免整数溢出。
在SQL Server 2012或更高版本中,您可以使用IIF和ISNULL(或COALESCE)的组合来获得最多2个值。 即使其中一个是NULL。
IIF(col1 >= col2, col1, ISNULL(col2, col1))
或者当两者都为NULL时,希望它返回0
IIF(col1 >= col2, col1, COALESCE(col2, col1, 0))
示例代码片段:
-- use table variable for testing purposes
declare @Order table
(
OrderId int primary key identity(1,1),
NegotiatedPrice decimal(10,2),
SuggestedPrice decimal(10,2)
);
-- Sample data
insert into @Order (NegotiatedPrice, SuggestedPrice) values
(0, 1),
(2, 1),
(3, null),
(null, 4);
-- Query
SELECT
o.OrderId, o.NegotiatedPrice, o.SuggestedPrice,
IIF(o.NegotiatedPrice >= o.SuggestedPrice, o.NegotiatedPrice, ISNULL(o.SuggestedPrice, o.NegotiatedPrice)) AS MaxPrice
FROM @Order o
结果:
OrderId NegotiatedPrice SuggestedPrice MaxPrice
1 0,00 1,00 1,00
2 2,00 1,00 2,00
3 3,00 NULL 3,00
4 NULL 4,00 4,00
但如果需要多列中的最大值呢? 然后我建议在值的聚合上使用CROSS APPLY。
例子:
SELECT t.*
, ca.[Maximum]
, ca.[Minimum], ca.[Total], ca.[Average]
FROM SomeTable t
CROSS APPLY (
SELECT
MAX(v.col) AS [Maximum],
MIN(v.col) AS [Minimum],
SUM(v.col) AS [Total],
AVG(v.col) AS [Average]
FROM (VALUES (t.Col1), (t.Col2), (t.Col3), (t.Col4)) v(col)
) ca
这有一个额外的好处,它可以同时计算其他的东西。
CREATE FUNCTION [dbo].[fnMax] (@p1 INT, @p2 INT)
RETURNS INT
AS BEGIN
DECLARE @Result INT
SET @p2 = COALESCE(@p2, @p1)
SELECT
@Result = (
SELECT
CASE WHEN @p1 > @p2 THEN @p1
ELSE @p2
END
)
RETURN @Result
END
是的,有。
T-SQL (SQL Server 2022 (16.x))现在支持最大/最小函数:
MAX/MIN作为非聚合函数 现在Azure SQL数据库和SQL托管实例都支持这个功能。它将滚动到下一个版本的SQL Server。
逻辑函数- GREATEST (Transact-SQL) 此函数返回一个或多个表达式列表中的最大值。 最伟大的表达,…n)
在这种情况下:
SELECT o.OrderId, GREATEST(o.NegotiatedPrice, o.SuggestedPrice)
FROM [Order] o;
db < > fiddle演示