2009-05-28 9 views
7

J'écris une vue de base de données pour résumer un groupe d'enregistrements où la valeur dans une colonne de date est au cours des 7 derniers jours. Il ressemble à ceci:Comment éviter l'utilisation de getdate() dans une vue 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 

Est-il possible de le faire sans avoir l'GETDATE() directement dans la clause where?

J'utilise SQL Server 2000 et 2005.

En regardant le plan de requête montre que le coût de l'appel getdate() est seulement 0,03% de l'ensemble de la requête (ce qui est beaucoup plus complexe que celui ci-dessus), donc la performance n'est pas un problème, mais j'aime que mes requêtes soient déterministes.

Idéalement, je voudrais également exposer le paramètre -7 en tant que colonne afin qu'il puisse être utilisé dans la clause where de quelque chose interrogeant la vue. Actuellement, j'envisage un petit nombre de vues pour les fenêtres de 7, 14 et 28 jours.

+0

Je ne sais pas si je comprends bien la question. Où serait-ce si ce n'était pas dans la clause where? Pensez-vous à une sorte de paramètre que vous transmettez? – micahtan

+0

Je suppose que c'est pour éviter le coup de performance de l'évaluation de GETDATE() pour chaque ligne du jeu de résultats. – Joe

+0

Pourquoi supposez-vous qu'il est évalué pour chaque rangée? – RedFilter

Répondre

6

L'une des raisons de votre question pourrait être de rendre la vue plus optimisable en supprimant la transformation de données. Ne peut pas le faire dans une vue, vous auriez besoin d'en faire une procédure stockée et faire la transformée en une variable:

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

j'ai mal compris la question, si vous essayez juste de déplacer GetDate() et non le remplacer, vous pouvez faire l'évaluation dans une clause HAVING-à-dire

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

Si je Je comprends bien la question, vous pouvez toujours essayer une jointure interne avec un ensemble qui contient GETDATE() comme dans la requête suivante:

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: J'ai examiné un plan de requête pour un scénario similaire, et ils sont identiques. YMMV.

2

Un autre coup dans le noir, comme tout le monde ...

Peut-être souhaitez-vous en faire une vue indexée, ce que vous ne pourriez pas faire avec getdate(), puisque c'est une fonction indéterminée. Je l'ai contourné par le passé en appelant getdate() dans une autre vue que contient uniquement

select getdate() 

Ce niveau d'indirection était suffisant pour tromper SQL Server 2000 et me permettre d'utiliser SCHEMABINDING, mais je ne peux pas garantir ce fonctionnera avec les versions ultérieures.

+0

Je vais vérifier celui-ci - merci – geofftnz

+0

Essayé en 2008. DId ne fonctionne pas, malheureusement 'Msg 4513, Niveau 16, État 2, Procédure view_ProductSearch, Ligne 5 [Batch Start Line 9] Impossible de schéma lier vue 'dbo .view_ProductSearch '. 'dbo.view_CurrentDate' n'est pas lié au schéma. ' –

+0

Ce n'est pas ce que je recommande, mais vous pouvez créer une fonction CLR qui renvoie la date actuelle et la marque comme IsDeterministic. – RedFilter

0

En supposant que vous avez des données là-dedans pour le dernier jour, une sous-requête pourrait peut-être travailler:

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 
Questions connexes