给定“多个分区”,用日历表填充所有日期空白的更好​​方法是什么?

时间:2018-07-26 14:35:41

标签: sql

任务是查找并填写缺失的年份,每个Make的平均值为avg_id。 Make是动态的,不能进行硬编码。

给出此日历表:

avg_year, avg_id
2011    , 1     
2012    , 2     
2013    , 3     
2014    , 4     
2015    , 14    
2016    , 15    
2017    , 16    
2010    , 5     
2009    , 6     
2008    , 7     

这些数据之间存在差距:

car_year, car_id, make         
2011    , 51    , 'BMW'        
2012    , 24    , 'BMW'        
2013    , 37    , 'BMW'        
2014    , 52    , 'BMW'        
2011    , 78    , 'Mitsubishi' 
2012    , 80    , 'Mitsubish'  
2014    , 99    , 'Mitsubishi' 
2008    , 101   , 'Audi'       
2008    , 102   , 'Audi'       
2013    , 102   , 'Audi'       
2015    , 103   , 'Audi'   

什么是获取此数据的更好方法:

CAR_YEAR,CAR_ID,MAKE       ,AVG_ID
2008    ,101   ,Audi       ,7     
2008    ,102   ,Audi       ,7     
2009    ,null  ,Audi       ,6     
2010    ,null  ,Audi       ,5     
2011    ,null  ,Audi       ,1     
2012    ,null  ,Audi       ,2     
2013    ,102   ,Audi       ,3     
2014    ,null  ,Audi       ,4     
2015    ,103   ,Audi       ,14    
2016    ,null  ,Audi       ,15    
2017    ,null  ,Audi       ,16    
2008    ,null  ,BMW        ,7     
2009    ,null  ,BMW        ,6     
2010    ,null  ,BMW        ,5     
2011    ,51    ,BMW        ,1     
2012    ,24    ,BMW        ,2     
2013    ,37    ,BMW        ,3     
2014    ,52    ,BMW        ,4     
2015    ,null  ,BMW        ,14    
2016    ,null  ,BMW        ,15    
2017    ,null  ,BMW        ,16    
2008    ,null  ,Mitsubishi ,7     
2009    ,null  ,Mitsubishi ,6     
2010    ,null  ,Mitsubishi ,5     
2011    ,78    ,Mitsubishi ,1     
2012    ,null  ,Mitsubishi ,2     
2013    ,null  ,Mitsubishi ,3     
2014    ,99    ,Mitsubishi ,4     
2015    ,null  ,Mitsubishi ,14    
2016    ,null  ,Mitsubishi ,15    
2017    ,null  ,Mitsubishi ,16    

pastebin link中,有针对此问题的解决方案。

问题不是“如何”,而是“如何做得更好”。

如果解决方案不是特定于供应商的,则表示荣誉。 (即按级别缺少连接)

相似的问题:fill-in-the-date-gaps-with-date-table

1 个答案:

答案 0 :(得分:0)

使用cross join生成行,并使用left join引入所需的数据:

select m.make, c.car_year, g.car_id, c.avg_id
from calendar c cross join
     (select distinct make from gaps) m left join
     gaps g
     on g.make = m.make and g.avg_year = c.car_year
order by m.make, c.car_year;