如何避免在SQL视图中使用getdate()?

时间:2009-05-28 23:06:18

标签: sql sql-server database view

我正在编写一个数据库视图来汇总一组记录,其中日期列中的值在过去7天内。它看起来像这样:

CREATE VIEW RecentRecordSum AS
SELECT      t.ID,   
            SUM(t.SomeValue) AS ValueSum
FROM        SomeTable t
WHERE       t.RecordDate >= DATEADD(d,-7,GETDATE())
GROUP BY    t.ID

有没有办法在没有直接在where子句中使用GETDATE()的情况下执行此操作?

我正在使用SQL Server 2000和2005。

查看查询计划显示getdate()调用的成本仅为整个查询的0.03%(这比上面的查询复杂得多),因此性能不是问题,但我喜欢我的查询是确定性的。

理想情况下,我还希望将-7参数公开为列,以便可以在查询视图的where子句中使用它。目前我正在考虑7,14,28天窗口的少量观看。

5 个答案:

答案 0 :(得分:6)

您的问题的一个原因可能是通过删除数据转换使视图更加可优化。无法在视图中执行此操作,您需要将其设置为存储过程并将变换转换为变量:

CREATE PROCEDURE RecentRecordSum AS

DECLARE @adate DATETIME

SELECT @adate = DATEADD(d, -7, GETDATE())

SELECT      t.ID,   
            SUM(t.SomeValue) AS ValueSum  
FROM        SomeTable t  
WHERE       t.RecordDate >= @adate  
GROUP BY    t.ID  

答案 1 :(得分:2)

黑暗中的另一个镜头,就像其他人一样......

也许你希望将它变成一个索引视图,你无法使用getdate(),因为它是一个不确定的函数。我过去通过从另一个只包含

的视图中调用getdate()来规避这一点
select getdate()

这种间接性足以欺骗SQL Server 2000并允许我使用架构绑定,但我无法保证这将适用于更高版本。

答案 2 :(得分:0)

SELECT CURRENT_TIMESTAMP

SELECT {fn NOW()}

我可能误解了这个问题,如果您只是试图移动GetDate()而不是替换它,您可以在Have子句中进行评估,即

CREATE VIEW RecentRecordSum AS
SELECT      t.ID,   
            SUM(t.SomeValue) AS ValueSum
FROM        SomeTable t
GROUP BY    t.ID, t.RecordDate
HAVING      t.RecordDate >= DATEADD(d,-7,GETDATE())

答案 3 :(得分:0)

如果我正确理解了这个问题,你总是可以尝试使用包含GETDATE()的集合进行内连接,如下面的查询所示:

SELECT      t.ID,   
            SUM(t.SomeValue) AS ValueSum
FROM        SomeTable t
INNER JOIN (SELECT DATEADD(d,-7,GETDATE()) AS MIN_DATE) MIN_DATE_SET
ON t.RecordDate >= MIN_DATE_SET.MIN_DATE
GROUP BY    t.ID

编辑: 我已经查看了类似场景的查询计划,它们是相同的。 YMMV。

答案 4 :(得分:0)

假设您最近一天有数据,子查询可能有效:

CREATE VIEW RecentRecordSum AS
SELECT      t.ID,   
            SUM(t.SomeValue) AS ValueSum
FROM        SomeTable t
WHERE       t.RecordDate >= DATEADD(d,-7,(Select Max(RecordDate) From SomeTable))
GROUP BY    t.ID