我想写一个这样的查询:
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))
其他回答
你可以这样做:
select case when o.NegotiatedPrice > o.SuggestedPrice
then o.NegotiatedPrice
else o.SuggestedPrice
end
如果你想拥有与你的例子相似的语法,你需要创建一个用户定义的函数,但是你能像其他人所说的那样,用一个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
在MemSQL中执行以下操作:
-- DROP FUNCTION IF EXISTS InlineMax;
DELIMITER //
CREATE FUNCTION InlineMax(val1 INT, val2 INT) RETURNS INT AS
DECLARE
val3 INT = 0;
BEGIN
IF val1 > val2 THEN
RETURN val1;
ELSE
RETURN val2;
END IF;
END //
DELIMITER ;
SELECT InlineMax(1,2) as test;
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)。
我会使用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
编辑 在Mark的评论后修改。正如他在3值逻辑x > NULL或x < NULL应该总是返回NULL。换句话说,未知的结果。