sql server语言 - T-SQL用户定义函数或类似的从值列表中计算最大值(日期)



假设我有一个源,我必须像这样查询:

Select Fields 
from TableA A
join TableB B on A.SomeField = B.SomeField
join TableC C on B.SomeField = C.SomeField
Join TableD D on C.SomeField = D.SomeField
Where 
    CustomMaxDateFunction (A.SomeDateField, B.SomeDateField, C.SomeDateField, D.SomeDateField) > '20130101 23:59:00'

我知道我可以像下面这样写where子句,但我宁愿不这样写:

Where 
  A.SomeDateField > '20130101 23:59:00' 
  OR B.SomeDateField > '20130101 23:59:00' 
  OR C.SomeDateField > '20130101 23:59:00' 
  OR D.SomeDateField > '20130101 23:59:00'

请记住,要比较的列数将根据连接中源表的数量而变化。

由于我们将不得不重复使用自定义函数(或存储过程),有什么最不麻烦的方法吗?

您可以直接使用内置的MAX聚合,而不是创建新函数。

SELECT MAX(v) FROM (VALUES(A.SomeDateField),(B.SomeDateFiled),(C.SomeDateField),(D.SomeDateField))dates(v)

或在您的查询上下文中:

SELECT *
FROM TableA AS A
JOIN TableB AS B
ON ...
JOIN TableC AS C
ON ...
JOIN TableD AS D
ON ...
WHERE (SELECT MAX(v) FROM (VALUES(A.SomeDateField),(B.SomeDateFiled),(C.SomeDateField),(D.SomeDateField))dates(v)) > '20130101 23:59:00'

如果不够清晰,可以将其包装成一个函数

CREATE FUNCTION dbo.CustomMaxDateFunction(@v1 DATETIME, @v2 DATETIME, @v3 DATETIME, @v4 DATETIME)
RETURNS TABLE
AS
  RETURN SELECT MAX(v) MaxDate FROM (VALUES(@v1),(@v2),(@v3),(@v4))dates(v);

然后像这样调用它:

SELECT *
FROM TableA AS A
JOIN TableB AS B
ON ...
JOIN TableC AS C
ON ...
JOIN TableD AS D
ON ...
CROSS APPLY dbo.CustomMaxDateFunction(A.SomeDateField, B.SomeDateFiled, C.SomeDateField, D.SomeDateField) AS mdf
WHERE mdf.MaxDate > '20130101 23:59:00'

在这个查询上下文中避免使用其他形式的函数,因为它们会影响性能:http://sqlity.net/en/498/t-sql-tuesday-24-prox-n-funx/

所有的函数都有一个共同点,那就是你被固定在一个给定的参数数量上,所以第一个选项可能是你最好的选择。

编辑:如果你真的喜欢函数的概念,你可以这样做:

CREATE FUNCTION dbo.CustomMaxDateFunction(@v1 DATETIME, @v2 DATETIME, @v3 DATETIME, @v4 DATETIME)
    RETURNS TABLE
    AS
      RETURN SELECT MAX(v) MaxDate FROM (VALUES(@v1),(@v2),(@v3),(@v4))dates(v) WHERE v IS NOT NULL;

现在你可以这样调用它:

SELECT *
FROM TableA AS A
JOIN TableB AS B
ON ...
CROSS APPLY dbo.CustomMaxDateFunction(A.SomeDateField, B.SomeDateFiled, NULL, NULL) AS mdf
WHERE mdf.MaxDate > '20130101 23:59:00'

实际上必须用NULL填充未使用的参数。函数中附加的WHERE子句可以防止关于消除NULL值的警告。正如RBarryYoung在评论中提到的,SQL Server中的函数没有真正的可选参数功能。

最新更新