Как избежать использования getdate () в представлении SQL? - PullRequest
7 голосов
/ 29 мая 2009

Я пишу представление базы данных, чтобы суммировать кучу записей, где значение в столбце даты находится в течение последних 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

Есть ли способ сделать это, не используя GETDATE () непосредственно в предложении where?

Я использую SQL Server 2000 и 2005.

Изучение плана запроса показывает, что стоимость вызова getdate () составляет всего 0,03% от всего запроса (что значительно сложнее, чем выше), поэтому производительность не является проблемой, однако мне нравятся мои запросы быть детерминированным.

В идеале я бы также хотел представить параметр -7 в виде столбца, чтобы его можно было использовать в предложении where чего-то, запрашивающего представление. В настоящее время я рассматриваю небольшое количество просмотров для окон 7, 14, 28 дней.

Ответы [ 5 ]

6 голосов
/ 29 мая 2009

Одной из причин вашего вопроса может быть улучшение представления путем удаления преобразования данных. Невозможно сделать это в представлении, вам нужно сделать его хранимой процедурой и преобразовать ее в переменную:

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  
2 голосов
/ 29 мая 2009

Еще один выстрел в темноте, как и все ...

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

select getdate()

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

0 голосов
/ 29 мая 2009

Предполагая, что у вас есть данные за последний день, подзапрос может работать:

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
0 голосов
/ 29 мая 2009

Если я правильно понимаю вопрос, вы всегда можете попробовать внутреннее соединение с набором, который содержит 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.

0 голосов
/ 29 мая 2009
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())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...