基于动物数据集中范围的列-SQL

问题描述

表格:

num       value      category      name
503       8978       bird          woodpecker
502       7812       animal        
502       7812       animal        
501       7812       animal        
500       7812       animal        panther
499       7812       animal        
498       7812       animal     
467       7812       animal        elephant           

在列partition byvalue的{​​{1}}中,应按以下方式创建输出列:
如果category不为null,则name列将占用output的值,并在num列的正2和负两个范围内填充相同的值。
例如,500具有name,500-2 = 498和500 + 2 = 502,在498到502的范围内,输出name not null填充

输出

panther

解决方法

尝试对大小写使用窗口功能:

select num,value,category,name,output from
(
--if num is in range [match_number-2,match_number+2] then get animal's name
select *,CASE when num>=(match_number-2) and num<=(match_number+2) then max_nam else NULL end as output from
 (
 --find num matching name
 select *,max( case when name=max_nam then num else 0 end )over (partition by value,category) match_number from
  (
  --find name (not null) partition by value,category 
   select *,max(name)over(partition by value,category)max_nam from Table
  )X
 )Y
)Z
,

您可以使用range窗框:

select t.*,coalesce(name,max(name) over (partition by category
                                order by num
                                range between 2 preceding and 2 following
                               )
               ) as imputed_name
from t;

Here是db 小提琴。

编辑:

在Postgres中,range窗口框架对“前置”和“跟随”的支持相对较新。在旧版本中,横向联接也许是最简单的方法:

select t.*,coalesce(t.name,t2.name) as imputed_name
from t left join lateral
     (select t2.name
      from t t2
      where t2.category = t.category and
            t2.name is not null and
            t2.num between t.num - 2 and t.num + 2
      limit 1
     ) t2
     on 1=1
order by num desc;

Here是该版本的db 小提琴。