回顾这个SO post
如果存在分组类别“类别”,为了简单起见,可以是X或Y--修改此脚本是否是一个微不足道的事情,以便它会为每个类别添加缺少的日期?
我认为该类别需要加入CTE?
换句话说,如果我有以下初始表:
...我如何进行以下操作:
将很快上传我的尝试
我称之为初始表#x。我希望调整如下所示的递归CTE查询以包含字段Category:
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
答案 0 :(得分: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
答案 1 :(得分:1)
这是一个没有日历表的解决方案(这是生产中必须的)。您可能在变量中有日期范围,或者您可以从the_table
获取min()和max()。
编辑:将类别纳入日期范围生成的较短版本
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)