2009-05-28 25 views
7

私は日付の列の値が過去7日以内にあるレコードの束を集計するデータベースビューを作成しています。これは次のようになります。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 

where節でGETDATE()を直接実行しないと、これを行う方法はありますか?

私はSQL Server 2000および2005

クエリプランを見てみるとGETDATE()呼び出しのコストは1よりもかなり複雑であるクエリ全体のわずか0.03%に(であることを示しているを使用してい

上記のように)、パフォーマンスは問題ではありませんが、私はクエリが決定論的であることが好きです。

理想的には、-7パラメータを列として公開して、ビューを照会するもののwhere句で使用できるようにしたいと思います。現在、私は7,14,28日のウィンドウのために少数のビューを検討しています。

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

わかりません。 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()を含むセットで内部結合を試みることができます。

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

つまりHAVING句での評価を行うことができますあなただけのGetDateを(移動しようとしている場合、私は、質問を誤解している可能性があり

2

皆のような暗闇の中で別のショット、...

おそらく、これは不確定関数なので、これをgetdate()で行うことができないインデックス付きのビューにしたいと思うかもしれません。私はちょうど間接のこのレベルは、SQL Server 2000をだます、私はSCHEMABINDINGを使用できるようにするには十分だった

select getdate() 

が含まれている別のビュー内からGETDATE()を呼び出すことで、過去にこれを回避しているが、私はこれを保証することはできませんそれ以降のバージョンで動作します。

+0

私はこれをチェックします - ありがとう – geofftnz

+0

2008年にこれを試してみました。DIzはうまくいきませんでした。 'メッセージ4513、レベル16、状態2、プロシージャview_ProductSearch、行5 [バッチ開始行9] ビュー 'dboをバインドできません。 .view_ProductSearch '。 'dbo.view_CurrentDate'はスキーマにバインドされていません。 –

+0

これはお勧めしませんが、現在の日付を返し、IsDeterministicとしてマークするCLR関数を作成することができます。 – 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 
関連する問題