Tsql 在SQL中获取两个值中的最小值
我有两个变量,一个叫做Tsql 在SQL中获取两个值中的最小值,tsql,sql-server,Tsql,Sql Server,我有两个变量,一个叫做paidthisnooth,另一个叫做OwedPast。它们都是SQL中某些子查询的结果。如何选择两者中较小的一个并将其作为标题为paidforfast的值返回 MIN函数作用于列,而不是变量。用例: Select Case When @PaidThisMonth < @OwedPast Then @PaidThisMonth Else @OwedPast End PaidForPast 增编: 这可能是最好的,当只处理两个可能
paidthisnooth
,另一个叫做OwedPast
。它们都是SQL中某些子查询的结果。如何选择两者中较小的一个并将其作为标题为paidforfast
的值返回
MIN
函数作用于列,而不是变量。用例:
Select Case When @PaidThisMonth < @OwedPast
Then @PaidThisMonth Else @OwedPast End PaidForPast
增编:
这可能是最好的,当只处理两个可能的值时,如果有两个以上的值,考虑使用值子句。使用case语句。
本页中的示例B应该与您尝试执行的操作非常接近:以下是页面中的代码:
使用AdventureWorks;
去
选择产品编号、名称、“价格范围”=
案例
当ListPrice=0时,则“制造品-不转售”
当标价<50时,则“低于50美元”
当ListPrice>=50且ListPrice<250时,则“低于250美元”
当ListPrice>=250且ListPrice<1000时,则“低于1000美元”
否则“超过1000美元”
结束
从生产。产品
按产品编号订购;
去
我只是遇到了一个情况,我必须在一次更新中找到最多4个复杂的选择。 使用这种方法,您可以拥有任意数量的产品 您还可以使用传统选择替换数字
select max(x)
from (
select 1 as 'x' union
select 4 as 'x' union
select 3 as 'x' union
select 2 as 'x'
) a
更复杂的用法
@answer = select Max(x)
from (
select @NumberA as 'x' union
select @NumberB as 'x' union
select @NumberC as 'x' union
select (
Select Max(score) from TopScores
) as 'x'
) a
我确信UDF具有更好的性能。使用临时表插入值的范围,然后从存储过程或UDF中选择临时表的最小值/最大值。这是一个基本的构造,所以可以根据需要随意修改 例如:
这最多可用于5个日期并处理空值。只是无法让它作为内联函数工作
CREATE FUNCTION dbo.MinDate(@Date1 datetime = Null,
@Date2 datetime = Null,
@Date3 datetime = Null,
@Date4 datetime = Null,
@Date5 datetime = Null)
RETURNS Datetime AS
BEGIN
--USAGE select dbo.MinDate('20120405',null,null,'20110305',null)
DECLARE @Output datetime;
WITH Datelist_CTE(DT)
AS (
SELECT @Date1 AS DT WHERE @Date1 is not NULL UNION
SELECT @Date2 AS DT WHERE @Date2 is not NULL UNION
SELECT @Date3 AS DT WHERE @Date3 is not NULL UNION
SELECT @Date4 AS DT WHERE @Date4 is not NULL UNION
SELECT @Date5 AS DT WHERE @Date5 is not NULL
)
Select @Output=Min(DT) FROM Datelist_CTE
RETURN @Output
END
SQL Server 2012和2014支持IIF(cont、true、false)函数。因此,对于最小的选择,您可以像
SELECT IIF(first>second, second, first) the_minimal FROM table
虽然只是编写
CASE…WHEN…ELSE
的简写,但编写起来更容易。使用CASE、IIF和UDF的解决方案是足够的,但如果将问题扩展到使用2个以上比较值的一般情况,则不切实际。广义
SQL Server 2008+中的解决方案利用了VALUES子句的一个奇怪应用程序:
SELECT
PaidForPast=(SELECT MIN(x) FROM (VALUES (PaidThisMonth),(OwedPast)) AS value(x))
本网站的信用:
如果要计算最大值(字段,0),这里有一个技巧:
如果
字段
为负值,则返回0,否则返回字段
基于mathematix和scottyc的精彩逻辑/代码,我提交:
DECLARE @a INT, @b INT, @c INT = 0
WHILE @c < 100
BEGIN
SET @c += 1
SET @a = ROUND(RAND()*100,0)-50
SET @b = ROUND(RAND()*100,0)-50
SELECT @a AS a, @b AS b,
@a - ( ABS(@a-@b) + (@a-@b) ) / 2 AS MINab,
@a + ( ABS(@b-@a) + (@b-@a) ) / 2 AS MAXab,
CASE WHEN (@a <= @b AND @a = @a - ( ABS(@a-@b) + (@a-@b) ) / 2)
OR (@a >= @b AND @a = @a + ( ABS(@b-@a) + (@b-@a) ) / 2)
THEN 'Success' ELSE 'Failure' END AS Status
END
声明@a INT、@b INT、@c INT=0
而@c<100
开始
设置@c+=1
设置@a=圆形(RAND()*100,0)-50
设置@b=圆形(RAND()*100,0)-50
选择@a作为a,@b作为b,
@a-(ABS(@a-@b)+(@a-@b))/2作为MINab,
@a+(ABS(@b-@a)+(@b-@a))/2作为MAXab,
当(@a=@b和@a=@a+(ABS(@b-@a)+(@b-@a))/2)时的情况
然后“成功”或“失败”以状态结束
结束
虽然scottyc的最小函数到最大函数的跳转对我来说应该是显而易见的,但事实并非如此,所以我已经解决了这个问题,并将其包含在这里:选择@a+(ABS(@b-@a)+(@b-@a))/2。随机生成的数字虽然不能证明,但至少应该让怀疑者相信这两个公式都是正确的。对于MySQL或PostgreSQL 9.3+,更好的方法是使用
最小的
和最大的
函数
SELECT GREATEST(A.date0, B.date0) AS date0,
LEAST(A.date1, B.date1, B.date2) AS date1
FROM A, B
WHERE B.x = A.x
与:
:从提供的值返回最大值(最大值)参数最大值(值[,…])
从提供的值返回最小的(最小值)参数LEAST(value[,…])
- MySQL
- 博士后
CASE…WHEN…ELSE
的一个语法糖。可能是的。但是写起来更容易。@MertGülsoy,也更容易阅读,这应该是每个人的优先事项列表的第一位,在正确之后。这应该是公认的答案。作为前端开发人员,CASE…WHEN…ELSE
阅读起来非常笨拙<代码>IIF更清晰、更短。IIF(仅要求SQLServerGTE2012支持,此答案,其他答案)因此,要计算最小值(@a,@b),您可以使用:选择@a-(ABS(@a-@b)+(@a-@b))/2,不要忘记类型溢出;)这是从浮点精度的角度保存的吗?可以肯定的是,结果永远不会接近于零,而是负值吗?我最喜欢这个,因为它是基本SQL。此外,UDF并不一定要快。对于大多数列存储,每个属性(我假设您也将对属性进行筛选)都可以并行计算,并且只合并符合条件的集合。所以工会本身并不慢。这在PostgreSQL中也适用(这正是我想要的:)请看:这是目前为止最好的答案。@RobertoRodriguez如果问题中有MySQL或PostgreSQL标记,那将是最好的。这个问题是专门针对tsql的,所以这个答案根本没有帮助。如果您希望最小值不为零,这不是MSSQL的答案:min(x*(如果为0,则为null,否则为1结束))
,但MartinC在四年前给出了相同的答案,并且实际显示了超过
SELECT IIF(first>second, second, first) the_minimal FROM table
SELECT
PaidForPast=(SELECT MIN(x) FROM (VALUES (PaidThisMonth),(OwedPast)) AS value(x))
SELECT (ABS(field) + field)/2 FROM Table
DECLARE @a INT, @b INT, @c INT = 0
WHILE @c < 100
BEGIN
SET @c += 1
SET @a = ROUND(RAND()*100,0)-50
SET @b = ROUND(RAND()*100,0)-50
SELECT @a AS a, @b AS b,
@a - ( ABS(@a-@b) + (@a-@b) ) / 2 AS MINab,
@a + ( ABS(@b-@a) + (@b-@a) ) / 2 AS MAXab,
CASE WHEN (@a <= @b AND @a = @a - ( ABS(@a-@b) + (@a-@b) ) / 2)
OR (@a >= @b AND @a = @a + ( ABS(@b-@a) + (@b-@a) ) / 2)
THEN 'Success' ELSE 'Failure' END AS Status
END
SELECT GREATEST(A.date0, B.date0) AS date0,
LEAST(A.date1, B.date1, B.date2) AS date1
FROM A, B
WHERE B.x = A.x