背景:我需要在SQL Server 2008 10.0.5869上的T-SQL中编写一个函数。
这是我正在处理的表格(为了简单起见 - 我这里只列出3列 - 但我有10列用于实际工作):
ID | Column1 | Column2 | Column3
1 | 2014-05 | 2015-02 | 2013-04
2 | 2012-09 | 2011-02 | 2013-03
ID是varchar,Column(x)都是日期时间。
我的最终目标是设计一个函数fn_CompareDate来执行以下操作:
select fn_CompareDate(ID) from table where ID = 1
上面的查询应返回列(x)的最新日期,该日期应为2015-02。
我使用了CASE WHEN,但几乎不可能将它用于10列。还有另一种方法可以达到相同的效果吗?
答案 0 :(得分:4)
一种方法是使用apply
:
select d.maxd
from table t cross apply
(select max(d) as maxd
from values ((id, column1), (id, column2), (id, column3)) as val(id, d)
where val.id = t.id
) d
where t.id = 1;
编辑:
您可以在不values()
的情况下执行此操作:
select d.maxd
from table t cross apply
(select max(d) as maxd
from (select id, column1 as d union all
select id, column2 union all
select id, column3 union all
select id, column4
) val
where t.id = val.id
) d
where t.id = 1;
答案 1 :(得分:2)
我认为以下功能可以更好地满足要求
CREATE FUNCTION fn_CompareDate(@ID VARCHAR(10))
RETURNS DATETIME
AS
BEGIN
DECLARE @maxDate DATETIME;
SELECT @maxDate =
(SELECT Max(v)
FROM (VALUES (COLUMN1), (COLUMN2), (COLUMN3)) AS value(v))
FROM table
WHERE ID = @ID
RETURN @maxDate;
END;
现在运行以下查询
select dbo.fn_CompareDate(ID) from table where ID = 1
希望你明白了。
答案 2 :(得分:1)
您可以使用动态sql和INFORMATION_SCHEMA.COLUMNS。它应该在SQL Server 2008中工作。试试这个:
CREATE PROCEDURE sp_CompareDate
@ID int,
@tableName NVARCHAR(MAX) = 'table2', -- Your table name
@dbName NVARCHAR(MAX) = 'temp' -- Your database name
AS
BEGIN
DECLARE @maxFieldValue DATETIME
DECLARE @curFieldName NVARCHAR(MAX)
DECLARE @curFieldValue DATETIME
DECLARE @sql NVARCHAR(MAX)
DECLARE fieldCursor CURSOR FOR
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @tableName
AND TABLE_CATALOG = @dbName AND COLUMN_NAME != 'ID'
OPEN fieldCursor
FETCH NEXT FROM fieldCursor INTO @curFieldName
SET @sql = N'USE [' + @dbName + N'] SELECT @curDate=' + @curFieldName
+ N' FROM ' + @tableName + N' WHERE ID=' + CAST(@ID AS NVARCHAR)
EXEC sp_executesql @sql, N'@curDate DATETIME output', @curFieldValue output;
SET @maxFieldValue = @curFieldValue
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @sql = N'USE [' + @dbName + N'] SELECT @curDate=' + @curFieldName
+ N' FROM ' + @tableName + N' WHERE ID=' + CAST(@ID AS NVARCHAR)
EXEC sp_executesql @sql, N'@curDate DATETIME output', @curFieldValue output;
FETCH NEXT FROM fieldCursor INTO @curFieldName
IF (@maxFieldValue < @curFieldValue) SET @maxFieldValue = @curFieldValue
END
CLOSE fieldCursor;
DEALLOCATE fieldCursor;
SELECT @maxFieldValue
END
希望这有帮助。
答案 3 :(得分:0)
我发现this question的第二个解决方案对我来说效果很好:
创建一个类似于此的函数:
select max(col) from
(
select column1 [col] from table where id = @id
union all
select column2 from table where id = @id
union all
select column3 from table where id = @id
)