我创建了以下函数来简化一段特别复杂的代码。
CREATE FUNCTION [dbo].[DSGetMinimumInt] (@First INT, @Second INT)
RETURNS INT
AS
BEGIN
IF @First < @Second
RETURN @First
RETURN @Second
END
但是,它仅适用于INT数据类型。我知道我可以为数字创建一个,可能为Varchar和Datetime创建一个。
是否可以创建一个主“最小”功能来处理它们?有没有人这样做过?
我用谷歌搜索了它,但是空了。
答案 0 :(得分:1)
除SQL Server
以外的所有主要数据库都支持LEAST
和GREATEST
,这些数据库可以执行您想要的操作。
在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)