当前位置:  开发笔记 > 编程语言 > 正文

SQL Server中是否有一个Max函数,它在.NET中采用Math.Max这两个值?

如何解决《SQLServer中是否有一个Max函数,它在.NET中采用Math.Max这两个值?》经验,为你挑选了10个好方法。

我想写一个这样的查询:

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

但这不是这个MAX功能的工作方式,对吧?它是一个聚合函数,因此它需要一个参数,然后返回所有行的MAX.

有谁知道怎么做我的方式?



1> MikeTeeVee..:

如果您使用的是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)


仅+1回答不需要访问创建过程/功能!
这比仅需要计算标量的CASE WHEN解决方案性能更差.
正是我想要的答案类型.使用函数很慢,这也适用于日期,这是我需要的.
虽然在确定2个值的MAX时,更简单的语法可能永远不值得性能损失,但是具有更多值的情况可能是不同的.即使获得4个值的MAX,CASE条款也会变得冗长,笨拙且容易出错,而VALUES条款仍然简单明了.
+1完美无缺,特别适合超过2列进行比较!

2> splattne..:

可以在一行中完成:

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

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


这是非常"肮脏"的"诡计".编程代码时应明确表达目标,但在您的情况下,它看起来像是从混淆竞赛中获取的代码.
它可能是"脏的",但它可能是具有简单SQL方言的数据库的唯一选择.
+1我相信你提供了最正确的方法."SELECT((@ val1 + @ val2)+ ABS(@ val1- @ val2))/ 2为MAX_OF_TWO"还要记住,"SELECT((@ val1 + @ val2) - ABS(@ val1- @ val2))/ 2为MIN_OF_TWO ".
我不同意marcias.代码本身不一定需要明确表达目标,只要注释允许人们解决它.如果你在代码(或任何地方)中进行任何复杂的数学方程式,有时很难让它自我描述.只要将其分解为更简单,更易于理解的部分,那就是正确的编程.
如果总和大于可以存储在int中,则这种方式会产生溢出错误:declare @ val1 int declare @ val2 int set @ val1 = 1500000000 set @ val2 = 1500000000 SELECT 0.5*((@ val1 + @ val2)+ ABS(@ val1 - @ val2)) - =>溢出错误
我以前从未见过这个.天才.
因为它不是立即显而易见的,所以这是有效的,因为`ABS`表达式计算最小值和最大值之间差异的大小.将其重新添加到最小值和最大值的总和使得总和是最大值的两倍(总是可以被2整除).除以2将返回最大值.我相信你可以通过减去`ABS`表达而不是添加来改变它来实现'MIN`的功能.
旧线程我知道,但这适用于日期(它使用上面的公式):`dateadd(dd,((datediff(dd,0,[Date1])+ datediff(dd,0,[Date2]))+ abs(datediff) (dd,0,[Date1]) - datediff(dd,0,[Date2])))/ 2,0)
整齐的数学技巧,但我畏惧做浮点运算以获得最多两个整数的想法.
@King,它不是浮点数,如果用`div 2`替换`*0.5`,它再次是整数数学.这在其他代码中也会非常好用,因为你避免了if-then跳转,从而避免了分支错误预测(显然是以更长的关键路径为代价).
太酷了!! 但case语句读起来更好。
有人制定了[证据](https://math.stackexchange.com/a/429630)♥

3> Kevin Crumle..:

你需要制作一个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


我会支持你的解决方案,我唯一要补充的是对NULL值的支持.如果你只修改最后一行:"return @ value2"读作:"return isnull(@ val2,@ val1)"然后如果其中一个值为null,则函数将返回not null值,否则它将作为正常
@Thomas强制性模因形象(不以任何方式对你有任何冒犯!)http://www.flickr.com/photos/16201371@N00/2375571206/
@xan当我真正提出这个问题时,我无法理解我的想法.显然不是太多.无论如何,谢谢你的回答.
这将是非常缓慢的,因为所有东西都是标量UDF.请改用内联UDF

4> Scott Langha..:

我不这么认为.前几天我想要这个.我得到的最接近的是:

SELECT
  o.OrderId,
  CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN o.NegotiatedPrice 
     ELSE o.SuggestedPrice
  END
FROM Order o


+1用于直接解决方案,但您不处理空值.
这是我最喜欢的方法.你没有冒出溢出的风险,并且它比splattne的解决方案(这很酷)没有那么神秘,而且我没有创建UDF的麻烦.在许多情况下,案例非常方便.

5> Xin..:

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

IIF(a>b, a, b)

而已.

(提示:要么小心null,因为a>b只要其中任何一个为null ,结果都将为false.因此b,在这种情况下将是结果)


如果其中一个值为"NULL",则结果将始终为第二个.
IIF()是CASE语句的语法糖。如果CASE条件的任何一个值为NULL,则结果将是第二个(ELSE)。
所以`IIF(a> b,a,COALESCE(b,a))`给出只有一个存在时的值

6> jbeanky..:
DECLARE @MAX INT
@MAX = (SELECT MAX(VALUE) 
               FROM (SELECT 1 AS VALUE UNION 
                     SELECT 2 AS VALUE) AS T1)



7> 小智..:

其他答案都很好,但如果你不得不担心有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



8> Martin Smith..:

子查询可以访问外部查询中的列,因此您可以使用此方法来使用聚合,例如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



9> SetFreeByTru..:

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).



10> kristof..:

我会使用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

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有