我有两个变量,一个叫PaidThisMonth,另一个叫OwedPast。它们都是SQL中一些子查询的结果。我如何选择两者中较小的一个,并将其作为一个名为PaidForPast的值返回?

MIN函数作用于列,而不是变量。


当前回答

SQL Server 2012和2014支持IIF(cont,true,false)函数。因此,对于最小的选择,你可以使用它像

SELECT IIF(first>second, second, first) the_minimal FROM table

虽然IIF只是CASE…WHEN…ELSE,写起来更容易。

其他回答

使用CASE、IIF和UDF的解决方案是足够的,但是当将问题扩展到使用超过2个比较值的一般情况时是不切实际的。广义 SQL Server 2008+中的解决方案利用VALUES子句的一个奇怪应用:

SELECT
PaidForPast=(SELECT MIN(x) FROM (VALUES (PaidThisMonth),(OwedPast)) AS value(x))

由于本网站: http://sqlblog.com/blogs/jamie_thomson/archive/2012/01/20/use-values-clause-to-get-the-maximum-value-from-some-columns-sql-server-t-sql.aspx

这里有一个技巧,如果你想计算最大值(字段,0):

SELECT (ABS(field) + field)/2 FROM Table

如果字段为负,则返回0,否则返回字段。

我遇到的情况是,我必须在一次更新中找到最多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有更好的性能。

基于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;

虽然从scottyc的MIN函数到MAX函数的跳跃对我来说应该是显而易见的,但它不是,所以我已经解决了它,并将其包含在这里:SELECT @a + (ABS(@b-@a) + (@b-@a)) / 2。这些随机生成的数字虽然不是证据,但至少应该让怀疑论者相信这两个公式都是正确的。

用例:

   Select Case When @PaidThisMonth < @OwedPast 
               Then @PaidThisMonth Else @OwedPast End PaidForPast

作为内联表值UDF

CREATE FUNCTION Minimum
(@Param1 Integer, @Param2 Integer)
Returns Table As
Return(Select Case When @Param1 < @Param2 
                   Then @Param1 Else @Param2 End MinValue)

用法:

Select MinValue as PaidforPast 
From dbo.Minimum(@PaidThisMonth, @OwedPast)

附录: 当只处理两个可能的值时,这可能是最好的,如果有两个以上,考虑Craig使用values子句的回答。