我想写一个这样的查询:

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

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

有人知道我的方法吗?


当前回答

对于上面关于大数字的答案,你可以在加减法之前做乘法。它有点笨重,但不需要石膏。(我不能说速度,但我认为它仍然非常快)

选择0.5*((@val1+@val2)+ ABS(@val1 - @val2)

更改

选择 @val1*0.5+@val2*0.5 + ABS(@val1*0.5 - @val2*0.5)

如果你想避免强制转换,至少有一个替代方案。

其他回答

如果你使用的是SQL Server 2008(或更高版本),那么这是更好的解决方案:

SELECT o.OrderId,
       (SELECT MAX(Price)
        FROM (VALUES (o.NegotiatedPrice),(o.SuggestedPrice)) AS AllPrices(Price))
FROM Order o

所有的信用和投票都应该去Sven对一个相关问题的答案,“多列的SQL MAX ?” 我说这是“最佳答案”,因为:

It doesn't require complicating your code with UNION's, PIVOT's, UNPIVOT's, UDF's, and crazy-long CASE statments. It isn't plagued with the problem of handling nulls, it handles them just fine. It's easy to swap out the "MAX" with "MIN", "AVG", or "SUM". You can use any aggregate function to find the aggregate over many different columns. You're not limited to the names I used (i.e. "AllPrices" and "Price"). You can pick your own names to make it easier to read and understand for the next guy. You can find multiple aggregates using SQL Server 2008's derived_tables like so: SELECT MAX(a), MAX(b) FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10) ) AS MyTable(a, b)

对于上面关于大数字的答案,你可以在加减法之前做乘法。它有点笨重,但不需要石膏。(我不能说速度,但我认为它仍然非常快)

选择0.5*((@val1+@val2)+ ABS(@val1 - @val2)

更改

选择 @val1*0.5+@val2*0.5 + ABS(@val1*0.5 - @val2*0.5)

如果你想避免强制转换,至少有一个替代方案。

以下是@Scott Langham用简单的NULL处理给出的答案:

SELECT
      o.OrderId,
      CASE WHEN (o.NegotiatedPrice > o.SuggestedPrice OR o.SuggestedPrice IS NULL) 
         THEN o.NegotiatedPrice 
         ELSE o.SuggestedPrice
      END As MaxPrice
FROM Order o

在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

这有一个额外的好处,它可以同时计算其他的东西。

对于SQL Server 2012:

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