Answers:
用例:
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答案。
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的解决方案是足够的,但是当使用两个以上的比较值将问题扩展到一般情况时,这是不切实际的。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-服务器t-sql.aspx
MIN(x*(case x when 0 then null else 1 end))
我只是遇到一种情况,我必须在一次更新中找到最多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的性能更好。
对于MySQL或PostgreSQL 9.3+,更好的方法是使用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
带有:
GREATEST(value [, ...])
:从提供的值中返回最大(最大值)的参数LEAST(value [, ...])
从提供的值中返回最小(最小值)的参数文档链接:
使用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
使用临时表插入值的范围,然后从存储过程或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
这最多可用于5个日期并处理null。只是无法使其用作内联函数。
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
我基于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.随机生成的数字虽然不能证明,但至少应使怀疑论者相信这两个公式都是正确的。