Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql 在SQL中获取两个值中的最小值_Tsql_Sql Server - Fatal编程技术网

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
  • 博士后

更好理解的语法:return(当@param1<@@param2然后@param1 else@@param2 end时选择minValue=case)。好吧,这可能没有正常化,我不知道。但这更容易理解,应该规范化。另一个喜欢@Craig回答的原因是空处理。如果要比较的值可以为null,并且要比较的值之一为null,则显示的开关案例可能会返回null或该值,具体取决于WHEN测试的顺序(除非添加使用ISNULL)。Craig的方法总是倾向于选择NOTNULL值,这对我来说似乎更正确,至少在我当前比较可空日期的用例中是这样。刚刚意识到你不需要WHERE子句,因为MIN无论如何都会删除空值。只是
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