我的 CTE 具有以下结构
ITEM, DATE, QUANTITY, EXTRA
AAAA 01-07-2015 100 20
AAAA 04-07-2015 100 13
AAAA 07-07-2015 100 16
AAAA 09-07-2015 100 23
.
.
.
AAAA 31-07-2015 100 30
基本上,我想要做的是获取其中包含“缺失日期”的记录以及包含上一条记录中的 EXTRA 的 EXTRA 字段(如下所示)
ITEM, DATE, QUANTITY, EXTRA
AAAA 01-07-2015 100 20
AAAA 02-07-2015 0 20
AAAA 03-07-2015 0 20
AAAA 04-07-2015 100 13
AAAA 05-07-2015 0 13
AAAA 06-07-2015 0 13
AAAA 07-07-2015 100 16
AAAA 08-07-2015 0 16
AAAA 09-07-2015 100 23
.
.
.
AAAA 31-07-2015 100 30
我可以使用 LAG 和包含有效日期完整列表 + MERGE 的临时表的组合来手动插入记录。然而,这个CTE只是用于一次性检查然后就被处理掉。有更好的办法吗?
试试这个;
;with tbl as (
--your data....
),
max_min_val as (
select max(date) as max_date, min(date) as min_date from tbl
),
all_date AS (
SELECT min_date as DateColumn
from max_min_val
UNION ALL
SELECT DATEADD(day,1,DateColumn)
FROM all_date, max_min_val
WHERE DATEADD(day,1,DateColumn) <= max_date
)
select
coalesce(t.item, (select top 1 tt.item from tbl tt where tt.date < x.DateColumn order by tt.date desc)) as item,
x.DateColumn as date,
coalesce(t.QUANTITY, 0) as QUANTITY,
coalesce(t.EXTRA, (select top 1 tt.EXTRA from tbl tt where tt.date < x.DateColumn order by tt.date desc)) as EXTRA
from all_date x
left join
tbl t on t.date = x.DateColumn
all_date
将包含 date
之间的所有 min and max date in tbl
。all_date
将给出所有日期coalesce(t.QUANTITY, 0) as QUANTITY
将给出 t.QUANTITY
如果 not null
否则 0
EXTRA
和 item
将根据 CTE tbl
给出来自 date
的前几行数据。考虑以下因素:
我制作了一个
CTE
代表您的数据(不考虑 ITEM
,因为它在示例中不相关)。
通过以下两个
CTE
,我正在使用 data
搜索可用 recursive query
的最小和最大之间缺失的日期。
接下来,您需要将右侧的
data
连接到可用的 dates
。关键是从 date
中获取最大 data
的行,只要 data.date
小于 dates.date
。
最后,我根据示例的解释是,你想继承
extra
,但不继承quantity
。因此 case
中的 select
语句。
with data as (
select cast('2015-07-01' as date) date, 100 quantity, 20 extra union all
select cast('2015-07-04' as date) date, 100 quantity, 13 extra union all
select cast('2015-07-07' as date) date, 100 quantity, 16 extra union all
select cast('2015-07-09' as date) date, 100 quantity, 23 extra
)
, maxDate as (
select MAX(date) date
from data
)
, dates as (
select date
from data
union all
select DATEADD(day,1,date) date
from dates
where DATEADD(day,1,date) not in (select date from data)
and DATEADD(day,1,date) < (select date from maxDate)
)
select dates.date
, case dates.date when data.date then data.quantity else 0 end quantity
, data.extra
from dates
join data on data.date = (select max(date) from data where data.date <= dates.date)
order by 1