在SQL中获取最少两个值

时间:2009-12-22 17:07:09

标签: tsql sql-server

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

的值返回

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

10 个答案:

答案 0 :(得分:111)

SQL Server 2012和2014支持IIF(cont,true,false)功能。因此,对于最小的选择,您可以像

一样使用它
SELECT IIF(first>second, second, first) the_minimal FROM table

答案 1 :(得分:107)

用例:

   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)

附录:     这可能最适合仅处理两个可能的值,如果有两个以上,请使用Values子句考虑Craig's answer

答案 2 :(得分:78)

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

答案 3 :(得分:28)

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

答案 4 :(得分:13)

对于MySQL或PostgreSQL,更好的方法是使用LEAST和GREATEST函数。

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

这两个都在这里描述:http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html

答案 5 :(得分:12)

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

postData
如果
<?php
    include "page1.php";
?>
<table class="table"> 
<thead> 
<tr> 
    <th>Name</th> 
    <th>Major</th> 
</tr>                                                     
</thead> 
<tbody>
<?php
    $number = $row['number'];
    $sql1 = "SELECT name, major FROM students WHERE number='$number'";											
    $result1 = $conn->query($sql1);											
    $value = $result1->fetch_object();

    echo "<tr>
    <td>".$value['name']."</td>
    <td>".$value['major']."</td>
    </tr>";
?> 

</tbody>
</table>
为否定,则

返回0,否则返回<?php include "page1.php"; ?> <table class="table"> <thead> <tr> <th>Name</th> <th>Major</th> </tr> </thead> <tbody> <?php $number = $row['number']; $sql1 = "SELECT name, major FROM students WHERE number='$number'"; $result1 = $conn->query($sql1); $value = $result1->fetch_object(); echo "<tr> <td>".$value['name']."</td> <td>".$value['major']."</td> </tr>"; ?> </tbody> </table>

答案 6 :(得分:5)

使用CASE声明。

此页面中的示例B应该接近您要执行的操作:
http://msdn.microsoft.com/en-us/library/ms181765.aspx

以下是该页面的代码:

USE AdventureWorks;
GO
SELECT   ProductNumber, Name, 'Price Range' = 
      CASE 
         WHEN ListPrice =  0 THEN 'Mfg item - not for resale'
         WHEN ListPrice < 50 THEN 'Under $50'
         WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250'
         WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000'
         ELSE 'Over $1000'
      END
FROM Production.Product
ORDER BY ProductNumber ;
GO

答案 7 :(得分:2)

使用临时表插入值范围,然后从存储过程或UDF中选择临时表的最小值/最大值。这是一个基本结构,因此可以随意修改。

例如:

CREATE PROCEDURE GetMinSpeed() AS
BEGIN

    CREATE TABLE #speed (Driver NVARCHAR(10), SPEED INT);
    '
    ' Insert any number of data you need to sort and pull from
    '
    INSERT INTO #speed (N'Petty', 165)
    INSERT INTO #speed (N'Earnhardt', 172)
    INSERT INTO #speed (N'Patrick', 174)

    SELECT MIN(SPEED) FROM #speed

    DROP TABLE #speed

END

答案 8 :(得分:2)

这适用于最多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

答案 9 :(得分:2)

基于来自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.随机生成的数字虽然不能证明,但至少应该使怀疑论者相信这两个公式都是正确的。