2009-05-28 2 views
7

Я пишу представление базы данных, чтобы суммировать кучу записей, где значение в столбце даты находится за последние 7 дней. Это выглядит примерно так:Как избежать использования getdate() в представлении SQL?

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

+0

Я предполагаю, что это делается для того, чтобы избежать удара производительности при оценке GETDATE() для каждой отдельной строки набора результатов. – Joe

+0

Почему вы предполагаете, что он оценивается для каждой строки? – RedFilter

ответ

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 

EDIT: Я рассмотрел план запросов для аналогичного сценария, и они идентичны. YMMV.

2

Другой выстрел в темноте, как и все остальные ...

Возможно, вы хотите сделать это индексированным представлением, которое вы не смогли бы использовать с getdate(), поскольку это неопределенная функция. Я обойти это в прошлом, вызвав GETDATE() из другой точки зрения, что только содержит

select getdate() 

Этот уровень косвенности было достаточно, чтобы обмануть SQL Server 2000 и позволит мне использовать SCHEMABINDING, но я не могу гарантировать, что это будет работать с более поздними версиями.

+0

Я проверю это - спасибо – geofftnz

+0

Пробовал это в 2008 году. DId не работает, к сожалению 'Msg 4513, Level 16, State 2, Procedure view_ProductSearch, Строка 5 [Начальная строка 9] Невозможно привязать представление схемы« dbo » .view_ProductSearch. 'dbo.view_CurrentDate' не привязан к схеме. ' –

+0

Не то, чтобы я рекомендую это, но вы можете создать функцию CLR, которая возвращает текущую дату, и пометьте ее как IsDeterministic. – RedFilter

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 
Смежные вопросы