with
t1 as (
select 'reb' as type, 1 as poss, 1 as ord, 'nick' as name union all
select 'reb' as type, 1 as poss, 2 as ord, null as name union all
select 'shot' as type, 1 as poss, 3 as ord, 'tom' as name union all
select 'reb' as type, 1 as poss, 4 as ord, null as name union all
select 'shot' as type, 1 as poss, 5 as ord, 'bil' as name union all
select 'reb' as type, 2 as poss, 1 as ord, null as name union all
select 'reb' as type, 2 as poss, 2 as ord, null as name union all
select 'shot' as type, 2 as poss, 3 as ord, 'joe' as name union all
select 'reb' as type, 2 as poss, 4 as ord, 'tim' as name union all
select 'shot' as type, 2 as poss, 4 as ord, 'tim' as name
)
select
first_value(name ignore nulls) over (partition by poss order by ord asc rows between unbounded preceding and unbounded following) as firstname
,*
from t1
这接近所需的输出,但并不完全正确。我们使用窗口函数来获取每个
poss
分区中出现的名字,按 ord
字段排序。
我们真正需要的是拍摄
name
的第一个 type
场。 firstname
的正确输出将是 tom tom tom tom tom joe joe joe joe joe
,因为 tom
是 poss == 1
中的第一个名称,基于类型拍摄的顺序。
select
first_value(if (type = 'shot', name, null) ignore nulls) over (
partition by poss -- if (type = 'shot', poss, null)
order by ord asc
rows between unbounded preceding and unbounded following
) as firstname
,*
from t1
order by poss asc, ord asc
这似乎是一个有效的解决方案,最初没有意识到
if()
语句可以在这样的窗口函数中使用。
与 t1 为 ( 选择“reb”作为类型,1 作为 poss,1 作为 ord,“nick”作为名称 union all 选择 'reb' 作为类型,1 作为 poss,2 作为 ord,null 作为名称 union all 选择“shot”作为类型,1 作为 poss,3 作为 ord,“tom”作为名称 union all 选择 'reb' 作为类型,1 作为 poss,4 作为 ord,null 作为名称 union all 选择“shot”作为类型,1 作为 poss,5 作为 ord,“bil”作为名称 union all 选择 'reb' 作为类型,2 作为 poss,1 作为 ord,null 作为名称 union all 选择 'reb' 作为类型,2 作为 poss,2 作为 ord,null 作为名称 union all 选择“shot”作为类型,2 作为 poss,3 作为 ord,“joe”作为名称 union all 选择“reb”作为类型,2 作为 poss,4 作为 ord,“tim”作为名称 union all 选择“shot”作为类型,2 作为 poss,4 作为ord,“tim”作为名称 )
选择 First_value(if(type='shot', name, null) 忽略空值) over(partition by poss order by poss) as firstname,* 来自 t1