日付 @x と日付 @y の間のすべての日付のテーブルを作成する簡単な方法 (できれば while ループを使用しない) が必要なだけなので、いくつかの統計テーブルへの外部結合を残すことができます。間の日、欠落している日を 0 でマークできるようにする
8 に答える
厳密に言えば、これはあなたの質問に正確に答えるものではありませんが、かなりきちんとしています。
開始日からの日数を指定して生きることができると仮定すると、共通テーブル式を使用すると次のようになります。
WITH numbers ( n ) AS (
SELECT 1 UNION ALL
SELECT 1 + n FROM numbers WHERE n < 500 )
SELECT DATEADD(day,n-1,'2008/11/01') FROM numbers
OPTION ( MAXRECURSION 500 )
適切な開始日から適切な終了日までのすべての日付を含む Calendar テーブルを作成します。これはデータベースのスペースをあまり占有しないため、これらのタイプのクエリは子供の遊びになります。
select ...
from Calendar
left outer join
...
where Calendar.Date >= @x
and Calendar.Date <= @y
すべての日付(Webサイトへの訪問者)を格納する別のテーブルを見つけたので、これはどうですか...
Declare @FromDate datetime,
@ToDate datetime
Declare @tmpDates table
(StatsDate datetime)
Set @FromDate = DateAdd(day,-30,GetDate())
Set @ToDate = GetDate()
Insert Into @tmpDates (StatsDate)
Select
distinct CAST(FLOOR(CAST(visitDate AS DECIMAL(12, 5))) AS DATETIME)
FROM tbl_visitorstats
Where visitDate between @FromDate And @ToDate
Order By CAST(FLOOR(CAST(visitDate AS DECIMAL(12, 5))) AS DATETIME)
Select * FROM @tmpDates
それは、私が望むすべての日付のエントリを持つ他のテーブルに依存していますが、98%は毎日のデータがある可能性があります。
実は少し前に似たようなことをしていたのですが、ループを使わない方法が思いつきませんでした。
私が得た最高のものは一時テーブルで、それに参加したい日付を選択しました。
リンク先のブログ bduke はかわいいですが、一時テーブルのソリューションはおそらくよりクリーンなソリューションだと思います。
whileループでそれを行うだけでもよいと思います。醜いことはわかっていますが、簡単で機能します。
ループを書くだけです。あなたであれ、SQL Serverであれ、誰かがこれのためのループを書かなければなりません。
DECLARE @Dates TABLE
(
TheDate datetime PRIMARY KEY
)
DECLARE @StartDate datetime, @EndDate datetime
SELECT @StartDate = '2000-01-01', @EndDate = '2010-01-01'
DECLARE @LoopVar int, @LoopEnd int
SELECT @LoopEnd = DateDiff(dd, @StartDate, @EndDate), @LoopVar = 0
WHILE @LoopVar <= @LoopEnd
BEGIN
INSERT INTO @Dates (TheDate)
SELECT DateAdd(dd,@LoopVar,@StartDate)
SET @LoopVar = @LoopVar + 1
END
SELECT *
FROM @Dates
ちょうど: WHERE 列 > 開始日 AND 列 < 終了日