5

日付データが欠落している場合、2 つの日付の間のすべての日付を表示したい場合は、val 列にゼロを表示する必要があります。

declare @temp table (
id int identity(1,1) not null,
CDate smalldatetime ,
val int
)

チェックするデータのステートメントを挿入

insert into @temp select '10/2/2012',1
insert into @temp select '10/3/2012',1
insert into @temp select '10/5/2012',1
insert into @temp select '10/7/2012',2
insert into @temp select '10/9/2012',2
insert into @temp select '10/10/2012',2
insert into @temp select '10/13/2012',2
insert into @temp select '10/15/2012',2

月の初日から今日までのレコードを取得する

select * from @temp where CDate between '10/01/2012' AND '10/15/2012'

このクエリを実行すると、これら2つの日付の間のすべてのデータが表示されますが、欠落している日付も含めたいですval=0

サンプル データを使用した SQL フィドル

4

6 に答える 6

10
;with d(date) as (
  select cast('10/01/2012' as datetime)
  union all
  select date+1
  from d
  where date < '10/15/2012'
  )
select t.ID, d.date CDate, isnull(t.val, 0) val
from d
left join temp t
       on t.CDate = d.date
order by d.date
OPTION (MAXRECURSION 0) -- use this if your dates are >99 days apart

日付を作成する必要があるため、ここでは再帰的な共通テーブル式を使用しています。 SQL フィドル

MAXRECURSION 数

このクエリで許可される再帰の最大数を指定します。number は、0 から 32767 までの負でない整数です。0 を指定すると、制限は適用されません。このオプションが指定されていない場合、サーバーのデフォルトの制限は 100 です。

クエリの実行中に MAXRECURSION 制限の指定された数またはデフォルトの数に達すると、クエリは終了し、エラーが返されます。

于 2012-10-15T07:32:40.043 に答える
3

from と to の日付の間が 2047 日未満である限り、これは機能します。

declare @from smalldatetime = '10/01/2012'
declare @to smalldatetime = '10/15/2012'

select t.id, dateadd(day, number,@from), isnull(val, 0) val from @temp t
right join master..spt_values s
on dateadd(d, s.number, @from) = t.CDate
where
datediff(day, @from, @to ) > s.number
and s.type = 'P'
于 2012-10-15T08:23:07.603 に答える
2

これを行う最善の方法は、日付を含む独自のテーブルを作成することだと思います (master.dbo.spt_values を使用することもできますが、個人的にはその解決策は好きではありません)。

declare @Temp_Dates table (CDate datetime)
declare @Date datetime
select @Date = (select min(CDate) from temp)

while @Date <= (select max(CDate) from temp)
begin
    insert into @Temp_Dates (CDate)
    select @Date

    select @Date = dateadd(dd, 1, @Date)
end

select D.CDate, isnull(T.id, 0) as id
from @Temp_Dates as D
    left outer join temp as T on T.CDate = D.CDate

CTEで再帰的なソリューションを使用することもできます

于 2012-10-15T07:34:59.307 に答える
2
DECLARE @min DATETIME, 
        @max DATETIME, 
        @val INT 

SELECT @min = Min(CDATE), 
       @max = Max(CDATE) 
FROM   TEMP 

DECLARE @temp TABLE 
  ( 
     CDATE SMALLDATETIME, 
     VAL   INT 
  ) 

WHILE @min < @max 
  BEGIN 
      SELECT @val = VAL 
      FROM   TEMP 
      WHERE  CDATE = @min 

      INSERT @temp 
      VALUES (@min, 
              @val) 

      SET @min = Dateadd(D, 1, @min) 
      SET @val = 0 
  END 

SELECT * 
FROM   @temp 
于 2012-10-15T07:36:45.747 に答える
1
Declare @temp Table(id int identity(1,1) not null,CDate smalldatetime ,val int)
insert into @temp select '10/2/2012',1
insert into @temp select '10/3/2012',1
insert into @temp select '10/5/2012',1
insert into @temp select '10/7/2012',2
insert into @temp select '10/9/2012',2
insert into @temp select '10/10/2012',2
insert into @temp select '10/13/2012',2
insert into @temp select '10/15/2012',2

DECLARE @startDate DATE= '10/01/2012'
DECLARE @endDate DATE= '10/15/2012'

SELECT t.Id, X.[Date],Val = COALESCE(t.val,0)
FROM 
    (SELECT [Date] = DATEADD(Day,Number,@startDate)  
    FROM  master..spt_values  
    WHERE Type='P' 
    AND DATEADD(day,Number,@startDate) <= @endDate)X
LEFT JOIN  @temp t 
ON X.[Date] = t.CDate

ここに画像の説明を入力してください

于 2012-10-15T08:42:11.360 に答える