在sql中获取两个值的最小值
我有两个variables,一个叫做PaidThisMonth
,另一个叫OwedPast
。 它们都是SQL中一些子查询的结果。 我怎样才能select两个中较小的一个,并将其作为标题为PaidForPast
的值PaidForPast
?
MIN
函数适用于列,而不是variables。
使用案例:
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)
SQL Server 2012和2014支持IIF(cont,true,false)函数。 因此,对于最小的select,你可以使用它
SELECT IIF(first>second, second, first) the_minimal FROM table
使用CASE,IIF和UDF的解决scheme是适当的,但使用两个以上的比较值将问题扩展到一般情况时是不切实际的。 SQL Server 2008+中的通用解决scheme使用了一个奇怪的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-服务器叔sql.aspx
我只是有一种情况,我必须在更新中find最多4个复杂select。 有了这个方法,你可以拥有尽可能多的!
您也可以使用aditionalselect来replace数字
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有更好的performance。
如果你想计算最大值(字段,0),这是一个技巧:
SELECT (ABS(field) + field)/2 FROM Table
如果field
为负,则返回0,否则返回field
。
使用CASE语句。
示例B应该接近您要做的: http : //msdn.microsoft.com/en-us/library/ms181765.aspx
这适用于最多5个date和处理空值。 只是不能让它作为一个内联函数工作。
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
如果你正在使用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 Bx = Ax
这两个在这里描述http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html
使用临时表来插入值的范围,然后从存储过程或UDF中select临时表的最小/最大值。 这是一个基本的构造,所以随意修改需要。
例如:
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
基于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
尽pipe从scottyc的MIN函数跳转到MAX函数对我来说应该是显而易见的,但它并不是,所以我已经解决了它并将其包含在这里:SELECT @a +(ABS(@ b- @ a)+( @ b- @ a))/ 2.随机生成的数字虽然不能certificate,但至less应使怀疑论者相信两个公式都是正确的。