如何为缺少的作业生成行?

时间:2019-06-19 19:06:54

标签: sql sql-server

假设我有一张学生桌,他们完成作业的日期以及他们的表现。例如:t1

Name     Date        Result 
Carlos   2019-06-01  Average 
Carlos   2019-06-02  Outstanding 
Carlos   2019-06-03  Outstanding 
Ernesto  2019-06-01  Average 
Ernesto  2019-06-02  Average 
Ernesto  2019-06-03  Failed 
Miguel   2019-06-02  Average 
Miguel   2019-06-03  Average
Ashley   2019-06-01  Outstanding 
Ashley   2019-06-02  Outstanding
Eddie    2019-06-01  Failed 
Eddie    2019-06-03  Failed

从表中可以看到,没有Miguel(2019-06-01),Ashley(2019-06-03)和Eddie(2019-06-02)的记录。在这种情况下,每当缺少作业时,我都想多产生一行。

我想生成一个像这样的新表:

Name     Date        Result 
Carlos   2019-06-01  Average 
Carlos   2019-06-02  Outstanding 
Carlos   2019-06-03  Outstanding 
Ernesto  2019-06-01  Average 
Ernesto  2019-06-02  Average 
Ernesto  2019-06-03  Failed
Miguel   2019-06-01  Missing      --New row
Miguel   2019-06-02  Average 
Miguel   2019-06-03  Average
Ashley   2019-06-01  Outstanding 
Ashley   2019-06-02  Outstanding
Ashley   2019-06-03  Missing      --New row
Eddie    2019-06-01  Failed
Eddie    2019-06-02  Missing      --New row
Eddie    2019-06-03  Failed

有任何线索吗?

谢谢大家!

3 个答案:

答案 0 :(得分:1)

您可以基于left joinname之间的交叉联接使用date结果表

select t3.name, t3.date, m.result 
from  (
  select  t2.name, t1.date
  from (
    select distinct date  
    from my_table  
  ) t1
  cross join (
   select distinct name  
   from my_table 
  ) t2 
) t3 
left join  my_table m  on m.name = t3.name and m.date = t3.date 

答案 1 :(得分:1)

使用cross join生成行,使用left join引入值:

select n.name, d.date, coalesce(t1.result, 'Missing') as result
from (select distinct name from t1) n cross join
     (select distinct date from t1) d left join
     t1
     on t1.name = n.name and t1.date = d.date;

答案 2 :(得分:-1)

如果希望将新生成的内容直接添加到表中,可以执行以下操作。

declare @MinDate        date,
        @MaxDate        date,
        @Name           varchar(30)

declare cur_std cursor for select distinct name from t1
open cur_std
fetch next from cur_std into @Name
while @@FETCH_STATUS = 0
begin
select @MinDate = Min(Date), @MaxDate = Max(Date) from t1
    while @MinDate <= @MaxDate
    begin
        if not exists (select * from t1 where Name = @Name and Date = @MinDate)
        begin
            insert into t1 values(@Name, @MinDate, 'Missing')
        end
        set @MinDate = DATEADD(dd,1,@MinDate)
    end

    fetch next from cur_std into @Name
end
close cur_std
deallocate cur_std

select * from t1