寻找一般的“最小”用户定义函数

时间:2010-02-18 14:33:36

标签: sql-server tsql

我创建了以下函数来简化一段特别复杂的代码。

CREATE FUNCTION [dbo].[DSGetMinimumInt] (@First INT, @Second INT)
RETURNS INT
AS
BEGIN
  IF @First < @Second
    RETURN @First
RETURN  @Second

END

但是,它仅适用于INT数据类型。我知道我可以为数字创建一个,可能为Varchar和Datetime创建一个。

是否可以创建一个主“最小”功能来处理它们?有没有人这样做过?

我用谷歌搜索了它,但是空了。

3 个答案:

答案 0 :(得分:1)

SQL Server以外的所有主要数据库都支持LEASTGREATEST,这些数据库可以执行您想要的操作。

SQL Server中,您可以通过以下方式模仿:

WITH    q (col1, col2) AS
        (
        SELECT  'test1', 'test2'
        UNION ALL
        SELECT  'test3', 'test4'
        )
SELECT  (
        SELECT  MIN(col)
        FROM    (
                SELECT  col1 AS col
                UNION ALL
                SELECT  col2
                ) qa
        )
FROM    q

,虽然效率会比UDF低一点。

答案 1 :(得分:1)

这是一个你可以使用的基本版本,我会小心在查询中使用它,因为它会减慢它们与其使用的行数成比例:

CREATE FUNCTION [dbo].[DSGetMinimum] (@First sql_variant, @Second sql_variant)
RETURNS varchar(8000)
AS
BEGIN
    DECLARE @Value   varchar(8000)

    IF SQL_VARIANT_PROPERTY(@First,'BaseType')=SQL_VARIANT_PROPERTY(@Second,'BaseType')
        OR @First IS NULL OR @Second IS NULL
    BEGIN
        IF SQL_VARIANT_PROPERTY(@First,'BaseType')='datetime'
        BEGIN
            IF CONVERT(datetime,@First)<CONVERT(datetime,@Second)
            BEGIN
                SET @Value=CONVERT(char(23),@First,121)
            END
            ELSE
            BEGIN
                SET @Value=CONVERT(char(23),@Second,121)
            END
        END --IF datetime
        ELSE
        BEGIN
            IF @First < @Second
                SET @Value=CONVERT(varchar(8000),@First)
            ELSE
                SET @Value=CONVERT(varchar(8000),@Second)
        END

    END --IF types the same

    RETURN  @Value

END
GO

修改
测试代码:

DECLARE @D1 datetime    , @D2 datetime
DECLARE @I1 int         , @I2 int
DECLARE @V1  varchar(5) , @V2 varchar(5)
SELECT @D1='1/1/2010', @D2='1/2/2010'
      ,@I1=5        , @I2=999
      ,@V1='abc'    , @V2='xyz'
PRINT dbo.DSGetMinimumInt(@D1,@D2)
PRINT dbo.DSGetMinimumInt(@I1,@I2)
PRINT dbo.DSGetMinimumInt(@V1,@V2)

测试输出:

2010-01-01 00:00:00.000
5
abc

如果你打算在查询中使用它,我只会使用一个内联CASE语句,它比UDF快得多:

CASE
    WHEN @valueAnyType1<@ValueAnyType2 THEN @valueAnyType1
    ELSE @ValueAnyType2
END

如果需要,您可以为NULL添加保护:

CASE
    WHEN @valueAnyType1<=ISNULL(@ValueAnyType2,@valueAnyType1) THEN @valueAnyType1
    ELSE @ValueAnyType2
END

答案 2 :(得分:1)

Azure SQL DB(以及未来的 SQL Server 版本)现在支持 GREATEST/LEAST:

GREATEST LEAST