2009-05-28 24 views
7

我正在写一个数据库视图来总结一堆日期列中的值在最近7天内的记录。它看起来是这样的:直接在where子句中如何避免在SQL视图中使用getdate()?

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 

是否有这样做的一种方式,而不必在GETDATE()?

我使用的是SQL Server 2000和2005

望着查询计划显示GETDATE()调用的成本仅为0.03%,整个查询(这是明显比一个更复杂以上),所以表现不是问题,但我喜欢我的查询是确定性的。

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

+0

不知道如果我理解这个问题。如果不在where子句中,它会在哪里?你是否想过通过某种参数? – micahtan 2009-05-28 23:12:16

+0

我假设这是为了避免对resultset的每一行评估GETDATE()的性能。 – Joe 2009-05-28 23:57:03

+0

为什么你认为它是每行评估? – RedFilter 2009-05-29 00:11:47

回答

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 
0
SELECT CURRENT_TIMESTAMP 

SELECT {fn NOW()} 

我可能误解了这个问题,如果你只是想移动GETDATE(),而不是取代它,你可以做一个HAVING子句即

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()) 
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 

编辑: 我看了一个类似的情况下查询计划,他们是相同的。因人而异。

2

另一个瞎猜,像其他人一样...

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

select getdate() 

这种间接的方法,足以骗过SQL Server 2000和允许我使用SCHEMABINDING另一个视图中调用GETDATE()规避这一点,但我不能保证这一点将与更高版本一起使用。

+0

我会检查这一个 - 谢谢 – geofftnz 2009-05-29 00:09:32

+0

在2008年尝试过。DId不工作,不幸的是'消息4513,级别16,状态2,过程视图_产品搜索,行5 [批次开始行9] 无法架构绑定视图'dbo .view_ProductSearch”。 'dbo.view_CurrentDate'不是模式绑定的。' – 2017-02-15 11:46:53

+0

不是我推荐的,但是您可以创建一个CLR函数,它返回当前日期并将其标记为IsDeterministic。 – RedFilter 2017-02-17 16:06:51

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