有没有在SQL Server中的.NET需要像Math.Max两个值一个最大的功能?(Is ther

2019-06-18 04:29发布

我想写这样的查询:

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

但是,这并不是如何MAX函数工作,对不对? 这是一个聚合函数,因此只需要一个参数,然后返回所有行MAX。

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

Answer 1:

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


Answer 2:

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

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

所有信用卡和票应该去斯文的回答一个相关的问题,“SQL MAX多个列的?”
我说这是“ 最好的回答 ”,因为:

  1. 它不要求你的代码联盟,PIVOT的,UNPIVOT的,UDF的,和疯狂的长CASE statments复杂。
  2. 它不与处理空值的问题所困扰,它处理他们就好了。
  3. 这很容易掉出来的“MAX”与“MIN”,“AVG”,或“SUM”。 您可以使用任何聚合函数发现在许多不同的列总和。
  4. 你不仅限于我使用(即“AllPrices”和“价格”)的名称。 你可以选择你自己的名字,以使其更易于阅读和理解未来的家伙。
  5. 您可以使用SQL Server 2008的找到多个聚集derived_tables像这样:
    SELECT MAX(a)中,MAX(B)选自(VALUES(1,2),(3,4),(5,6),(7,8),(9,10))AS MyTable的(A,B)


Answer 3:

可以在一个行来完成:

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

编辑: 如果你正在处理非常大的数字,你就必须到值的变量转换为BIGINT以避免整数溢出。



Answer 4:

我不认为如此。 我想这个的一天。 我得到的最接近是:

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


Answer 5:

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

IIF(a>b, a, b)

而已。

(提示:小心要么是null的,因为结果a>b将是错误的,只要要么是空,因此, b会是这个结果在这种情况下)



Answer 6:

DECLARE @MAX INT
@MAX = (SELECT MAX(VALUE) 
               FROM (SELECT 1 AS VALUE UNION 
                     SELECT 2 AS VALUE) AS T1)


Answer 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


Answer 8:

子查询可以从外部查询访问的列,所以你可以用这种方法来使用骨料,比如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


Answer 9:

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_expression将导致IIF返回false_value (而不是NULL )。



Answer 10:

我将与所提供的解决方案去kcrumley只是修改它稍微处理空值

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 <指出NULL应该总是返回NULL。 换句话说未知的结果。



Answer 11:

它如此简单:

CREATE FUNCTION InlineMax
(
    @p1 sql_variant,
    @p2 sql_variant
)  RETURNS sql_variant
AS
BEGIN
    RETURN CASE 
        WHEN @p1 IS NULL AND @p2 IS NOT NULL THEN @p2 
        WHEN @p2 IS NULL AND @p1 IS NOT NULL THEN @p1
        WHEN @p1 > @p2 THEN @p1
        ELSE @p2 END
END;


Answer 12:

哎呀,我刚刚发布了这一问题的欺骗 ......

答案是,没有内置的功能类似甲骨文的伟大 ,但是你能达到2列有UDF,注意类似的结果,使用的sql_variant是非常重要的位置。

create table #t (a int, b int) 

insert #t
select 1,2 union all 
select 3,4 union all
select 5,2

-- option 1 - A case statement
select case when a > b then a else b end
from #t

-- option 2 - A union statement 
select a from #t where a >= b 
union all 
select b from #t where b > a 

-- option 3 - A udf
create function dbo.GREATEST
( 
    @a as sql_variant,
    @b as sql_variant
)
returns sql_variant
begin   
    declare @max sql_variant 
    if @a is null or @b is null return null
    if @b > @a return @b  
    return @a 
end


select dbo.GREATEST(a,b)
from #t

克里斯托夫

发布这样的回答:

create table #t (id int IDENTITY(1,1), a int, b int)
insert #t
select 1,2 union all
select 3,4 union all
select 5,2

select id, max(val)
from #t
    unpivot (val for col in (a, b)) as unpvt
group by id


Answer 13:

下面是应该处理空值,并会与旧版本MSSQL的作业的情况下的例子。 这是基于在广受欢迎的一个例子一个内联函数:

case
  when a >= b then a
  else isnull(b,a)
end


Answer 14:

我可能不会做这种方式,因为它比已经提到的情况构建效率较低 - 除非,也许,你已经涵盖了这两个查询索引。 无论哪种方式,它是类似的问题一个有用的技术:

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


Answer 15:

下面是一个IIF版本NULL处理(根据新的回答):

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


Answer 16:

SELECT o.OrderId,   
--MAX(o.NegotiatedPrice, o.SuggestedPrice)  
(SELECT MAX(v) FROM (VALUES (o.NegotiatedPrice), (o.SuggestedPrice)) AS value(v)) as ChoosenPrice  
FROM Order o


Answer 17:

你可以这样做:

select case when o.NegotiatedPrice > o.SuggestedPrice 
then o.NegotiatedPrice
else o.SuggestedPrice
end


Answer 18:

SELECT o.OrderID
CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN
 o.NegotiatedPrice
ELSE
 o.SuggestedPrice
END AS Price


Answer 19:

CREATE FUNCTION [dbo].[fnMax] (@p1 INT, @p2 INT)
RETURNS INT
AS BEGIN

    DECLARE @Result INT

    SET @p2 = COALESCE(@p2, @p1)

    SELECT
        @Result = (
                   SELECT
                    CASE WHEN @p1 > @p2 THEN @p1
                         ELSE @p2
                    END
                  )

    RETURN @Result

END


Answer 20:

对于上述关于大量的答案,你可以在加法/减法之前做乘法。 这是一个有点笨重,但不要求演员。 (我不能代表速度,但我认为它仍然是相当快)

SELECT 0.5 *((@ VAL1 + @ val2次)+ ABS(@ VAL1 - @ val2次))

更改

SELECT @ VAL1 * 0.5 + @ val2的* 0.5 + ABS(@ VAL1 * 0.5 - @ val2的* 0.5)

至少一个选择,如果你想避免铸造。



Answer 21:

在最简单的形式...

CREATE FUNCTION fnGreatestInt (@Int1 int, @Int2 int )
RETURNS int
AS
BEGIN

    IF @Int1 >= ISNULL(@Int2,@Int1)
        RETURN @Int1
    ELSE
        RETURN @Int2

    RETURN NULL --Never Hit

END


Answer 22:

对于SQL Server 2012:

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


Answer 23:

在SQL Server 2012或更高版本,可以使用组合IIFISNULL (或COALESCE ),以获得最大的2个的值。
即使其中1为NULL。

IIF(col1 >= col2, col1, ISNULL(col2, col1)) 

或者,如果你希望它返回0时都为null

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


Answer 24:

这里是@Scott朗廷简单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


Answer 25:

select OrderId, (
    select max([Price]) from (
        select NegotiatedPrice [Price]
        union all
        select SuggestedPrice
    ) p
) from [Order]


Answer 26:

在普雷斯托你可以使用使用

SELECT array_max(ARRAY[o.NegotiatedPrice, o.SuggestedPrice])


Answer 27:

 -- Simple way without "functions" or "IF" or "CASE"
 -- Query to select maximum value
 SELECT o.OrderId
  ,(SELECT MAX(v)
   FROM (VALUES (o.NegotiatedPrice), (o.SuggestedPrice)) AS value(v)) AS MaxValue
  FROM Order o;


Answer 28:

扩展上新的答案,假设比较值类型是int,这种做法也工作:

SELECT IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)

这是一个完整的测试与示例值:

DECLARE @A AS INT
DECLARE @B AS INT

SELECT  @A = 2, @B = 1
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 2

SELECT  @A = 2, @B = 3
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 3

SELECT  @A = 2, @B = NULL
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 2    

SELECT  @A = NULL, @B = 1
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 1


文章来源: Is there a Max function in SQL Server that takes two values like Math.Max in .NET?