SQL 服务器 - 创建视图以检索给定日期之前的最新值
SQL Server - Create view retrieving most recent value before a given date
假设我在 SQL 服务器 (2012) 中有以下 table:
MyTable:
Date1: Col1: Val:
1/1/2016 c1 Val1
1/2/2016 c1 Val2
1/3/2016 c2 Val3
1/4/2016 c2 Val4
1/5/2016 c2 Val5
1/6/2016 c3 Val6
1/7/2016 c3 Val7
1/8/2016 c3 Val8
我想创建一个视图,对于 Col1 中的每个值,returns,对于给定日期,Val[=17 中的最新值=]
所以我的观点是:
MyView:
Date1: Col1: Val:
1/2/2016 c1 Val2
1/5/2016 c2 Val5
1/8/2016 c3 Val8
而且,更具体地说,我可以查询我的观点,例如:
SELECT * FROM MyView WHERE Date1 < '1/6/2016'
Result:
Date1: Col1: Val:
1/2/2016 c1 Val2
1/5/2016 c2 Val5
1/6/2016 c3 Val6
SELECT * FROM MyView WHERE Date1 <= '1/4/2016'
Result:
Date1: Col1: Val:
1/2/2016 c1 Val2
1/4/2016 c2 Val4
我可以编写嵌套/cte 查询来执行此操作,如下所示:
SELECT
Date1
, Col1
, Val
FROM (
SELECT
Date1
, Col1
, Val
, ROW_NUMBER() OVER (PARTITION BY Col1 ORDER BY Col1, Date1 DESC) as version_num
FROM
MyTable
WHERE
Date1 <= '1/6/2016'
) orderedtable
WHERE
version_num = 1
但我不知道如何将这个确切的查询转换为结果根据查询日期而变化的视图,或者如果视图中未指定日期,则仅返回最后/最新值-查询。
我一直在研究 LAST_VALUE(),但我发现它也不起作用。
有什么想法吗?
这能做到吗?
您似乎在搜索参数化视图。在 SQL Server
中,您不能将变量传递给视图,但您可以使用 table-valued function:
CREATE FUNCTION dbo.my_func(@d DATE)
RETURNS TABLE
AS
RETURN(
SELECT Date1
,Col1
,Val
FROM (SELECT
Date1
,Col1
,Val
,ROW_NUMBER() OVER (PARTITION BY Col1 ORDER BY Date1 DESC) as version_num
FROM MyTable
WHERE Date1 <= @d
) orderedtable
WHERE version_num = 1)
GO
SELECT *
FROM dbo.my_func('1/6/2016') -- it behaves as normal table
-- JOIN/WHERE ...
输出:
╔═════════════════════╦══════╦══════╗
║ Date1 ║ Col1 ║ Val ║
╠═════════════════════╬══════╬══════╣
║ 02.01.2016 00:00:00 ║ c1 ║ Val2 ║
║ 05.01.2016 00:00:00 ║ c2 ║ Val5 ║
║ 06.01.2016 00:00:00 ║ c3 ║ Val6 ║
╚═════════════════════╩══════╩══════╝
编辑:
如果您想要用户可以传递的所有值 NULL
:
SELECT *
FROM dbo.my_func(NULL);
变化:WHERE Date1 <= @d
到 WHERE Date1 <=ISNULL(@d, '2099-01-01T00:00:00')
或使用DEFAULT
:
CREATE FUNCTION dbo.my_func(@d DATE = '2099-01-01T00:00:00')
...
SELECT *
FROM dbo.my_func(default);
假设我在 SQL 服务器 (2012) 中有以下 table:
MyTable:
Date1: Col1: Val:
1/1/2016 c1 Val1
1/2/2016 c1 Val2
1/3/2016 c2 Val3
1/4/2016 c2 Val4
1/5/2016 c2 Val5
1/6/2016 c3 Val6
1/7/2016 c3 Val7
1/8/2016 c3 Val8
我想创建一个视图,对于 Col1 中的每个值,returns,对于给定日期,Val[=17 中的最新值=]
所以我的观点是:
MyView:
Date1: Col1: Val:
1/2/2016 c1 Val2
1/5/2016 c2 Val5
1/8/2016 c3 Val8
而且,更具体地说,我可以查询我的观点,例如:
SELECT * FROM MyView WHERE Date1 < '1/6/2016'
Result:
Date1: Col1: Val:
1/2/2016 c1 Val2
1/5/2016 c2 Val5
1/6/2016 c3 Val6
SELECT * FROM MyView WHERE Date1 <= '1/4/2016'
Result:
Date1: Col1: Val:
1/2/2016 c1 Val2
1/4/2016 c2 Val4
我可以编写嵌套/cte 查询来执行此操作,如下所示:
SELECT
Date1
, Col1
, Val
FROM (
SELECT
Date1
, Col1
, Val
, ROW_NUMBER() OVER (PARTITION BY Col1 ORDER BY Col1, Date1 DESC) as version_num
FROM
MyTable
WHERE
Date1 <= '1/6/2016'
) orderedtable
WHERE
version_num = 1
但我不知道如何将这个确切的查询转换为结果根据查询日期而变化的视图,或者如果视图中未指定日期,则仅返回最后/最新值-查询。
我一直在研究 LAST_VALUE(),但我发现它也不起作用。
有什么想法吗? 这能做到吗?
您似乎在搜索参数化视图。在 SQL Server
中,您不能将变量传递给视图,但您可以使用 table-valued function:
CREATE FUNCTION dbo.my_func(@d DATE)
RETURNS TABLE
AS
RETURN(
SELECT Date1
,Col1
,Val
FROM (SELECT
Date1
,Col1
,Val
,ROW_NUMBER() OVER (PARTITION BY Col1 ORDER BY Date1 DESC) as version_num
FROM MyTable
WHERE Date1 <= @d
) orderedtable
WHERE version_num = 1)
GO
SELECT *
FROM dbo.my_func('1/6/2016') -- it behaves as normal table
-- JOIN/WHERE ...
输出:
╔═════════════════════╦══════╦══════╗
║ Date1 ║ Col1 ║ Val ║
╠═════════════════════╬══════╬══════╣
║ 02.01.2016 00:00:00 ║ c1 ║ Val2 ║
║ 05.01.2016 00:00:00 ║ c2 ║ Val5 ║
║ 06.01.2016 00:00:00 ║ c3 ║ Val6 ║
╚═════════════════════╩══════╩══════╝
编辑:
如果您想要用户可以传递的所有值 NULL
:
SELECT *
FROM dbo.my_func(NULL);
变化:WHERE Date1 <= @d
到 WHERE Date1 <=ISNULL(@d, '2099-01-01T00:00:00')
或使用DEFAULT
:
CREATE FUNCTION dbo.my_func(@d DATE = '2099-01-01T00:00:00')
...
SELECT *
FROM dbo.my_func(default);