3

このSO投稿を参照する

簡単にするために、XまたはYのいずれかになるグループ化カテゴリ「Category」がある場合、各カテゴリに欠落している日付を追加するようにこのスクリプトを修正するのは簡単なことですか?

カテゴリを CTE に追加する必要があると思いますか?

つまり、次の初期テーブルがある場合:

ここに画像の説明を入力

...どうすれば次のようになります:

ここに画像の説明を入力

まもなく試行をアップロードします

最初のテーブルを #x と呼びました。次のような再帰的な CTE クエリを適応させて、フィールド カテゴリを含めることを望んでいます。

DECLARE @MinDate DATETIME; 
SET @MinDate =  (SELECT Min(DATE) FROM #x)

DECLARE @MaxDate DATETIME; 
SET @MaxDate =  (SELECT Max(DATE) FROM #x)

;WITH times AS 
    ( 
    SELECT @MinDate dt , 1 depth 
    UNION ALL 
    SELECT 
            DATEADD(d, depth, @MinDate) dt 
            , 1 + depth as depth 
    FROM times 
    WHERE DATEADD(d, depth, @MinDate) <= @MaxDate
    ) 
SELECT 
    * 
FROM 
    TIMES t
    LEFT OUTER JOIN #X x
        ON 
        t.dt = x.Date

わかりました-CROSS JOINを含めて結びましたが、間違って展開されます:

SELECT DISTINCT Category INTO #Cat FROM #x

DECLARE @MinDate DATETIME; 
SET @MinDate =  (SELECT Min(DATE) FROM #x)

DECLARE @MaxDate DATETIME; 
SET @MaxDate =  (SELECT Max(DATE) FROM #x)


;WITH times AS 
    ( 
    SELECT 
            Category
            , @MinDate dt 
            , 1 depth 
    FROM #Cat
    UNION ALL 
    SELECT 
            c.Category
            , DATEADD(d, depth, @MinDate) dt 
            , 1 + depth as depth 
    FROM 
            times t
            CROSS JOIN #Cat c
                --ON c.Category IS NOT NULL
    WHERE DATEADD(d, depth, @MinDate) <= @MaxDate
    ) 
SELECT 
    * 
FROM 
    TIMES

これはうまくいったようです:

SELECT DISTINCT Category INTO #Cat FROM #x

DECLARE @MinDate DATETIME; 
SET @MinDate =  (SELECT Min(DATE) FROM #x)

DECLARE @MaxDate DATETIME; 
SET @MaxDate =  (SELECT Max(DATE) FROM #x)


;WITH times AS 
    ( 
    SELECT 
            Category
            , @MinDate dt 
            , 1 depth 
    FROM #Cat
    UNION ALL 
    SELECT 
            Category
            , DATEADD(d, depth, @MinDate) dt 
            , 1 + depth as depth 
    FROM 
            times t
    WHERE DATEADD(d, depth, @MinDate) <= @MaxDate
    ) 
SELECT 
    * 
FROM 
    TIMES
4

2 に答える 2

1

このような何かがうまくいくはずです:

declare @curDate datetime, @maxDate datetime
declare @count tinyint

select @curDate = convert(datetime, '20120101', 112), @maxDate = getdate()
select @count = 0

while @curDate < @maxDate
begin
  select @count = count(1) from tablename where Category = 'X' and convert(varchar(8), Date, 112) = convert(varchar(8), @curDate, 112)

  if @count > 0
  begin
    insert into tablename
    select 'X', @curDate, 0
  end

  select @curDate = dateadd(dd, 1, @curDate)
end
于 2012-06-14T10:41:40.390 に答える
1

これは、カレンダーテーブルを使用しないソリューションです (これは本番環境では必須です)。変数に日付範囲がある場合や、min() と max() from を使用する場合がありますthe_table

EDIT:日付範囲の生成にカテゴリを組み込んだ短いバージョン

declare @startdate datetime = '2012-1-1'
declare @enddate datetime = '2012-1-5'

; with dates([date], category) as (
  select distinct @startdate, category
    from the_table
   union all
  select dateadd (day, 1, [date]), category
    from dates
   where [date] < @enddate
)
select dates.date, 
       dates.category, 
       isnull(the_table.amount, 0) Amount
  from dates
  left join the_table
    on dates.date = the_table.date
   and dates.category = the_table.category
 order by dates.category, dates.date
option (maxrecursion 0)

ライブ テスト @ Sql Fiddle があります。 新しい SQL フィドル

于 2012-06-14T11:07:24.610 に答える