我想写一个这样的查询:

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

但这不是MAX函数的工作原理,对吧?它是一个聚合函数,因此它需要一个参数,然后返回所有行的MAX。

有人知道我的方法吗?


当前回答

可以在一行中完成:

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

编辑:如果处理的是非常大的数字,则必须将值变量转换为bigint,以避免整数溢出。

其他回答

是的,有。

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演示

为什么不尝试IIF功能(需要SQL Server 2012及更高版本)

IIF(a>b, a, b)

就是这样。

(额外提示:小心a或b是否为空,因为在这种情况下,>b的结果将为假。因此,如果任意一个为空,则返回结果为b)(同样根据系统设计,列为空也不是一个好的实践)

我可能不会这样做,因为它比前面提到的CASE结构效率更低——除非您为两个查询都有覆盖索引。不管怎样,对于类似的问题,这都是一个有用的技巧:

SELECT OrderId, MAX(Price) as Price FROM (
   SELECT o.OrderId, o.NegotiatedPrice as Price FROM Order o
   UNION ALL
   SELECT o.OrderId, o.SuggestedPrice as Price FROM Order o
) as A
GROUP BY OrderId

在Presto你可以使用

SELECT array_max(ARRAY[o.NegotiatedPrice, o.SuggestedPrice])

SQL Server 2012引入IIF:

SELECT 
    o.OrderId, 
    IIF( ISNULL( o.NegotiatedPrice, 0 ) > ISNULL( o.SuggestedPrice, 0 ),
         o.NegotiatedPrice, 
         o.SuggestedPrice 
    )
FROM 
    Order o

建议在使用IIF时处理NULL,因为boolean表达式两侧的NULL将导致IIF返回false_value(而不是NULL)。