在日期为关键字的CTE中插入“缺失记录”

时间:2015-08-11 08:43:59

标签: sql-server tsql common-table-expression

我有一个具有以下结构的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仅用于一次性检查然后处理。还有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

请考虑以下事项:

我制作了代表您数据的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

答案 1 :(得分:0)

试试这个;

;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
  1. 此处all_datedate之间的所有min and max date in tbl
  2. 左连接all_date将提供所有日期
  3. 如果coalesce(t.QUANTITY, 0) as QUANTITY其他t.QUANTITY ,则
  4. not null0
  5. EXTRAitem会根据CTE tbldate提供以前的行数据。