如何为 db2 Sql 中的每一列汇总不具有空值的记录?

Posted

技术标签:

【中文标题】如何为 db2 Sql 中的每一列汇总不具有空值的记录?【英文标题】:How to rollup records having not null values for each column in db2 Sql? 【发布时间】:2021-10-07 15:26:25 【问题描述】:

我有一张如下表-

id name col1 col2 col3
1 aaa 1 null null
1 aaa null 1 null
1 aaa null null 1
1 aaa null null 2
1 aaa null 1 null
2 bbb null null null
2 bbb 1 null null

我希望输出如下-

id name col1 col2 col3
1 aaa 1 1 1
1 aaa null 1 2
2 bbb 1 null null

我试过这样做:

select id ,name, max(col1),max(col2),max(col3) 
from table group by id, name;

但是输出是这样的,和预期的不一样

id name col1 col2 col3
1 aaa 1 1 2

您能帮我实现所需的输出吗? 非常感谢。

【问题讨论】:

你必须解释你想要的输出背后的逻辑是什么。目前尚不清楚您希望如何根据提供的示例数据生成这两行 或许group by id, name, greatest(col1, col2, col3)? HI @eshirvana 感谢您的回复,我想将第一行中的所有记录合并,如表 2 所示,但如果有多个非空值,则创建下一条记录列。我所做的尝试给了我最大值并返回我不想要的单行,我想要所有值,组的记录数应该是 = 到具有最大非空值的列。希望这可以解释。 @jarlh 你能在这里详细说明一下,这是如何工作的。 我的问题是它有效吗?添加更多的样本数据,有不同的组合,看看你是否仍然认为它有效。 【参考方案1】:

您可以按原样尝试。

首先,枚举由(id, name)列指定的每个组中的行。请注意,如果您不在 row_number 函数中使用 order by 子句(如示例中所示),则此类枚举可能会以某种不可重复和不可预测的方式完成。所以,如果你想要一个可重复的结果,你应该有一种方法来明确地对行进行排序。我添加了一个额外的行,您可以使用它取消注释 order by 子句以获得您在问题中指定的确切结果。

其次,使用递归公用表表达式语句处理每个组中的行。引入了一个新的代理列 grp(每个组内的附加组号)。每组的第一行(具有 rn_=1)获取所有原始值和 grp=1。如果下一行的 c1、c2 或 c3 的值不为空,并且对应列的上一行的值也不为空,则下一行的 grp 值加 1。 如果组号不增加,则复制前一行的非空值,而不是每个 cx 的当前值。 如果增加,则保留当前行值。

最后,我们在 group by 子句中使用这个代理组号。dbfiddle link。

with mytab (id, name, c1, c2, c3, ord) as
(
values
  (1, 'aaa', 1, null::int, null::int, 10)
, (1, 'aaa', null, 1, null, 20)
, (1, 'aaa', null, null, 1, 30)
, (1, 'aaa', null, null, 2, 40)
, (1, 'aaa', null, 1, null, 50)
, (2, 'bbb', null, null, null, 1)
, (2, 'bbb', 1, null, null, 2)
)
-- Rows enumeration inside all groups
, mytab2 as 
(
select row_number () over (partition by id, name
--order by ord
) rn_, t.*
from mytab t
)
--
, a (id, name, rn_, grp, c1, c2, c3) as
(
select id, name, rn_, 1 as grp, c1, c2, c3 
from mytab2
where rn_ = 1
  union all
select t.id, t.name, t.rn_
, a.grp 
+ case 
    when a.c1 is not null and t.c1 is not null
      or a.c2 is not null and t.c2 is not null
      or a.c3 is not null and t.c3 is not null
    then 1
    else 0
  end as grp
, case 
    when a.c1 is not null and t.c1 is not null
      or a.c2 is not null and t.c2 is not null
      or a.c3 is not null and t.c3 is not null
    then t.c1
    else coalesce (a.c1, t.c1)
  end as c1
, case 
    when a.c1 is not null and t.c1 is not null
      or a.c2 is not null and t.c2 is not null
      or a.c3 is not null and t.c3 is not null
    then t.c2
    else coalesce (a.c2, t.c2)
  end as c2
, case 
    when a.c1 is not null and t.c1 is not null
      or a.c2 is not null and t.c2 is not null
      or a.c3 is not null and t.c3 is not null
    then t.c3
    else coalesce (a.c3, t.c3)
  end as c3
from a, mytab2 t
where t.id = a.id and t.name = a.name and t.rn_ = a.rn_ + 1
)
select id, name
, max (c1) as c1
, max (c2) as c2
, max (c3) as c3
from a
group by id, name, grp

【讨论】:

以上是关于如何为 db2 Sql 中的每一列汇总不具有空值的记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Handsontable 中的每一列定义自定义验证器

SQL汇总了最后一行中的每一列

如何为熊猫数据框的每一列应用具有不同时间常数的一阶过滤器?

如何为表格中的每一行制作一个接受按钮?

对 SQL 中的每一列求和并在行中显示它们

Pig如何为列分配名称?