我想写一个这样的查询:
SELECT o.OrderId, MAX(o.NegotiatedPrice, o.SuggestedPrice) FROM Order o
但这不是这个MAX
功能的工作方式,对吧?它是一个聚合函数,因此它需要一个参数,然后返回所有行的MAX.
有谁知道怎么做我的方式?
如果您使用的是SQL Server 2008(或更高版本),那么这是更好的解决方案:
SELECT o.OrderId, (SELECT MAX(Price) FROM (VALUES (o.NegotiatedPrice),(o.SuggestedPrice)) AS AllPrices(Price)) FROM Order o
所有的信用和投票应该转到Sven对相关问题的回答,"多列的SQL MAX?"
我说这是" 最佳答案 ",因为:
它不需要使用UNION,PIVOT,UNPIVOT,UDF和疯狂的CASE语句使您的代码复杂化.
它没有处理空值的问题,它处理它们就好了.
用"MIN","AVG"或"SUM"换出"MAX"很容易.您可以使用任何聚合函数来查找许多不同列上的聚合.
您不仅限于我使用的名称(即"AllPrices"和"Price").您可以选择自己的名字,以便下一个人更容易阅读和理解.
您可以使用SQL Server 2008的derived_tables找到多个聚合,如下所示:
SELECT MAX(a),MAX(b)FROM(VALUES(1,2),(3,4),(5,6),(7,8), (9,10))AS MyTable(a,b)
可以在一行中完成:
-- the following expression calculates ==> max(@val1, @val2) SELECT 0.5 * ((@val1 + @val2) + ABS(@val1 - @val2))
编辑: 如果你处理非常大的数字,你必须将值变量转换为bigint,以避免整数溢出.
你需要制作一个User-Defined Function
如果你想要的语法类似于你的例子,但是你可以CASE
像其他人所说的那样,用一个语句来内联,相当容易地做你想做的事情.
该UDF
会是这样的:
create function dbo.InlineMax(@val1 int, @val2 int) returns int as begin if @val1 > @val2 return @val1 return isnull(@val2,@val1) end
......你会这样称呼它......
SELECT o.OrderId, dbo.InlineMax(o.NegotiatedPrice, o.SuggestedPrice) FROM Order o
我不这么认为.前几天我想要这个.我得到的最接近的是:
SELECT o.OrderId, CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN o.NegotiatedPrice ELSE o.SuggestedPrice END FROM Order o
为什么不尝试IIF功能(需要SQL Server 2012及更高版本)
IIF(a>b, a, b)
而已.
(提示:要么小心null
,因为a>b
只要其中任何一个为null ,结果都将为false.因此b
,在这种情况下将是结果)
DECLARE @MAX INT @MAX = (SELECT MAX(VALUE) FROM (SELECT 1 AS VALUE UNION SELECT 2 AS VALUE) AS T1)
其他答案都很好,但如果你不得不担心有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
子查询可以访问外部查询中的列,因此您可以使用此方法来使用聚合,例如MAX
跨列.(当涉及更多列时,可能更有用)
;WITH [Order] AS ( SELECT 1 AS OrderId, 100 AS NegotiatedPrice, 110 AS SuggestedPrice UNION ALL SELECT 2 AS OrderId, 1000 AS NegotiatedPrice, 50 AS SuggestedPrice ) SELECT o.OrderId, (SELECT MAX(price)FROM (SELECT o.NegotiatedPrice AS price UNION ALL SELECT o.SuggestedPrice) d) AS MaxPrice FROM [Order] o
SQL Server 2012介绍IIF
:
SELECT o.OrderId, IIF( ISNULL( o.NegotiatedPrice, 0 ) > ISNULL( o.SuggestedPrice, 0 ), o.NegotiatedPrice, o.SuggestedPrice ) FROM Order o
在使用时建议处理NULL IIF
,因为NULL
在你的任何一方boolean_expression
都会导致IIF
返回false_value
(而不是NULL
).
我会使用kcrumley提供的解决方案 只需稍微修改它来处理NULL
create function dbo.HigherArgumentOrNull(@val1 int, @val2 int) returns int as begin if @val1 >= @val2 return @val1 if @val1 < @val2 return @val2 return NULL end
编辑
从评论后修改马克.正如他在3值逻辑中正确指出的那样x> NULL或x