子查询从行获取最新列值并将结果折叠为单行

时间:2017-03-15 03:18:16

标签: sql postgresql

我有一个表从主查询输出此结果,按降序日期排序(最新为顶部)

 colA         colb      colc
 ----------------------------
 null         null      null
 True         null      null
 False        null      null
 null         True      null
 null         null      False 

我希望最终结果看起来像这样

 colA     colB   colC
 -----------------------
 True     True   False

可以使用bool_or聚合函数,但在这种情况下它不会起作用:

 colA         colb      colc
 -----------------------------
 null         null      null
 False        null      null
 True         null      null
 null         True      null
 null         null      False 

这个的输出是

 colA      colB   colC
 ----------------------
 False     True   False

基本上,我需要遍历每一列中的每一行,并获得非空的最早值并返回该值。

到目前为止,我使用first_value获取窗口函数来获取第一个值,但遗憾的是表中的所有行

select first_value(cola) over() as cola 
from my_data 
where cola is not null;

返回

  cola
  -----
   f
   f 

如果我尝试为其他列执行first_value,它将不会返回任何内容,因为每列中的行数不匹配

这样做的最佳方式是什么?

1 个答案:

答案 0 :(得分:1)

with t (date, cola, colb, colc) as ( values
    (current_date, null,  null,  null),
    (current_date - 1, true,  null,  null),
    (current_date - 2, false, null,  null),
    (current_date - 3, null,  true,  null),
    (current_date - 4, null,  null,  false)
)
select
    (array_agg(fv_cola) filter (where fv_cola is not null))[1] as cola,
    (array_agg(fv_colb) filter (where fv_colb is not null))[1] as colb,
    (array_agg(fv_colc) filter (where fv_colc is not null))[1] as colc
from (
    select
        first_value(cola) over(
            partition by cola is null
            order by date desc
        ) as fv_cola,
        first_value(colb) over(
            partition by colb is null
            order by date desc
        ) as fv_colb,
        first_value(colc) over(
            partition by colc is null
            order by date desc
        ) as fv_colc
    from t
) s
;
 cola | colb | colc 
------+------+------
 t    | t    | f