我想写一个这样的查询:
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。
有人知道我的方法吗?
当前回答
在Presto你可以使用
SELECT array_max(ARRAY[o.NegotiatedPrice, o.SuggestedPrice])
其他回答
其他答案都很好,但如果你不得不担心有NULL值,你可能会想要这个变体:
SELECT o.OrderId,
CASE WHEN ISNULL(o.NegotiatedPrice, o.SuggestedPrice) > ISNULL(o.SuggestedPrice, o.NegotiatedPrice)
THEN ISNULL(o.NegotiatedPrice, o.SuggestedPrice)
ELSE ISNULL(o.SuggestedPrice, o.NegotiatedPrice)
END
FROM Order o
对于上面关于大数字的答案,你可以在加减法之前做乘法。它有点笨重,但不需要石膏。(我不能说速度,但我认为它仍然非常快)
选择0.5*((@val1+@val2)+ ABS(@val1 - @val2)
更改
选择 @val1*0.5+@val2*0.5 + ABS(@val1*0.5 - @val2*0.5)
如果你想避免强制转换,至少有一个替代方案。
这里有一个案例示例,应该处理null,并将与旧版本的MSSQL一起工作。这是基于一个流行例子中的内联函数:
case
when a >= b then a
else isnull(b,a)
end
在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
这有一个额外的好处,它可以同时计算其他的东西。
我可能不会这样做,因为它比前面提到的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