skb*_*skb 457 sql sql-server max
我想写一个这样的查询:
SELECT o.OrderId, MAX(o.NegotiatedPrice, o.SuggestedPrice)
FROM Order o
Run Code Online (Sandbox Code Playgroud)
但这不是这个MAX功能的工作方式,对吧?它是一个聚合函数,因此它需要一个参数,然后返回所有行的MAX.
有谁知道怎么做我的方式?
Mik*_*Vee 437
如果您使用的是SQL Server 2008(或更高版本),那么这是更好的解决方案:
SELECT o.OrderId,
(SELECT MAX(Price)
FROM (VALUES (o.NegotiatedPrice),(o.SuggestedPrice)) AS AllPrices(Price))
FROM Order o
Run Code Online (Sandbox Code Playgroud)
所有的信用和投票应该转到Sven对相关问题的回答,"多列的SQL MAX?"
我说这是" 最佳答案 ",因为:
spl*_*tne 216
可以在一行中完成:
-- the following expression calculates ==> max(@val1, @val2)
SELECT 0.5 * ((@val1 + @val2) + ABS(@val1 - @val2))
Run Code Online (Sandbox Code Playgroud)
编辑: 如果你处理非常大的数字,你必须将值变量转换为bigint,以避免整数溢出.
Kev*_*ley 151
你需要制作一个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
Run Code Online (Sandbox Code Playgroud)
......你会这样称呼它......
SELECT o.OrderId, dbo.InlineMax(o.NegotiatedPrice, o.SuggestedPrice)
FROM Order o
Run Code Online (Sandbox Code Playgroud)
Sco*_*ham 124
我不这么认为.前几天我想要这个.我得到的最接近的是:
SELECT
o.OrderId,
CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN o.NegotiatedPrice
ELSE o.SuggestedPrice
END
FROM Order o
Run Code Online (Sandbox Code Playgroud)
Xin*_*Xin 76
为什么不尝试IIF功能(需要SQL Server 2012及更高版本)
IIF(a>b, a, b)
Run Code Online (Sandbox Code Playgroud)
而已.
(提示:要么小心null,因为a>b只要其中任何一个为null ,结果都将为false.因此b,在这种情况下将是结果)
jbe*_*nky 32
DECLARE @MAX INT
@MAX = (SELECT MAX(VALUE)
FROM (SELECT 1 AS VALUE UNION
SELECT 2 AS VALUE) AS T1)
Run Code Online (Sandbox Code Playgroud)
Luk*_*zda 26
就在这里。
T-SQL (SQL Server 2022 (16.x)) 现在支持 GREATEST/LEAST 函数:
此功能现已适用于 Azure SQL 数据库和 SQL 托管实例。它将进入下一版本的 SQL Server。
逻辑函数 - GREATEST (Transact-SQL)
此函数返回一个或多个表达式列表中的最大值。
Run Code Online (Sandbox Code Playgroud)GREATEST ( expression1 [ ,...expressionN ] )
所以在这种情况下:
SELECT o.OrderId, GREATEST(o.NegotiatedPrice, o.SuggestedPrice)
FROM [Order] o;
Run Code Online (Sandbox Code Playgroud)
Luk*_*rms 18
在 SQL Server 2012 或更高版本中,您可以使用IIF和ISNULL(或COALESCE)的组合来获取最多 2 个值。
即使其中 1 个为 NULL。
IIF(col1 >= col2, col1, ISNULL(col2, col1))
Run Code Online (Sandbox Code Playgroud)
或者,如果您希望它在两者都为 NULL 时返回 0
IIF(col1 >= col2, col1, COALESCE(col2, col1, 0))
Run Code Online (Sandbox Code Playgroud)
示例片段:
-- 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
Run Code Online (Sandbox Code Playgroud)
结果:
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
Run Code Online (Sandbox Code Playgroud)
但是,如果需要最多的多列呢?
然后我建议对 VALUES 的聚合进行 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
Run Code Online (Sandbox Code Playgroud)
这有一个额外的好处,它可以同时计算其他东西。
小智 10
其他答案都很好,但如果你不得不担心有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
Run Code Online (Sandbox Code Playgroud)
子查询可以访问外部查询中的列,因此您可以使用此方法来使用聚合,例如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
Run Code Online (Sandbox Code Playgroud)
小智 7
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
Run Code Online (Sandbox Code Playgroud)
SQL Server 2012介绍IIF:
SELECT
o.OrderId,
IIF( ISNULL( o.NegotiatedPrice, 0 ) > ISNULL( o.SuggestedPrice, 0 ),
o.NegotiatedPrice,
o.SuggestedPrice
)
FROM
Order o
Run Code Online (Sandbox Code Playgroud)
在使用时建议处理NULL IIF,因为NULL在你的任何一方boolean_expression都会导致IIF返回false_value(而不是NULL).
我可能不会这样做,因为它比已经提到的 CASE 构造效率低 - 除非您可能覆盖两个查询的索引。无论哪种方式,对于类似的问题来说,这都是一种有用的技术:
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
Run Code Online (Sandbox Code Playgroud)
我会使用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
Run Code Online (Sandbox Code Playgroud)
编辑 从评论后修改马克.正如他在3值逻辑中正确指出的那样x> NULL或x <NULL应始终返回NULL.换句话说,未知的结果.
哎呀,我刚刚发布了这个问题的一个骗局......
答案是,没有像Oracle 的 Greatest这样的内置函数,但是您可以使用 UDF 对 2 列实现类似的结果,注意,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
Run Code Online (Sandbox Code Playgroud)
发布了这个答案:
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
Run Code Online (Sandbox Code Playgroud)
就这么简单:
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;
Run Code Online (Sandbox Code Playgroud)
尝试这个。它可以处理 2 个以上的值
SELECT Max(v) FROM (VALUES (1), (2), (3)) AS value(v)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
424429 次 |
| 最近记录: |