如何避免列组织数据处理和行组织数据处理之间的转换
Posted
技术标签:
【中文标题】如何避免列组织数据处理和行组织数据处理之间的转换【英文标题】:How to avoid transition between column-organized data processing and row-organized data processing 【发布时间】:2020-02-19 21:08:04 【问题描述】:我正在使用按列组织的表来开发 DB2 Blu。
我的数据集如下:
Day month year value
------- -------
20200101 202001 2020 100
20200102 202001 2020 110
...
20200215 202002 2020 120
我想按周、月和年汇总此结果:
Id value
2020 12000
202001 4000 'january
202002 4000 'february
2020001 700 'first week of 2020
为了做到这一点,我还有表 d_tps
Type Id week month year
J 20200101 2020001 202001 2020
J 20200102 2020001 202001 2020
...
J 20200215 2020007 202002 2020
M 202001 null 202001 2020
M 202002 null 202002 2020
Y 2020 null null 2020
我的方法如下
select d.id, sum(value) from tab1
Inner join d_tps d
On d.id = tab1.year
Or d.id = tab1.month
Or d.id = tab1.year
group by d.id
它工作并返回预期的结果。不幸的是,在查询计划中,使用 OR 条件连接会导致 CTQ 运算符提前出现,并且大多数查询(实际上更复杂)被视为行而不是列。
如何优化它?
【问题讨论】:
UNION ALL 单独选择周/月/年?只有一周需要加入。 Tab1 实际上是一个子查询,所以我想避免联合,因为性能是可读性 【参考方案1】:看起来一个join
条件加上聚合就足够了:
select d.week, sum(value)
from tab1 Inner join
d_tps d
On d.id = tab1.day
group by d.week
如果要按多个时间级别聚合,请使用grouping sets
:
select d.week, d.month, d.year, sum(value)
from tab1 Inner join
d_tps d
On d.id = tab1.day
group by grouping sets ((d.week), (d.month), (d.year))
【讨论】:
我不知道分组集。我明天试试。 缺少关键字:group by GROUPING SETS ((d.week), (d.month), (d.year))
确实缺少关键字。否则,它会完全按预期工作,谢谢!
@dnoeth 。 . .谢谢。【参考方案2】:
你应该使用GROUP BY GROUPING SETS
& GROUPING
函数来实现你想要的。
WITH T (day, month, year, value) AS
(
values
(20200101, 202001, 2020, 100)
, (20200102, 202001, 2020, 110)
, (20200215, 202002, 2020, 120)
)
SELECT
CASE
WHEN GROUPING(DAY) = 0 THEN DAY
WHEN GROUPING(MONTH) = 0 THEN MONTH
WHEN GROUPING(YEAR ) = 0 THEN YEAR
END AS ID
, SUM(VALUE) AS VALUE
FROM T
GROUP BY GROUPING SETS (DAY, MONTH, YEAR);
结果是:
|ID |VALUE |
|-----------|-----------|
|2020 |330 |
|202001 |210 |
|202002 |120 |
|20200101 |100 |
|20200102 |110 |
|20200215 |120 |
【讨论】:
以上是关于如何避免列组织数据处理和行组织数据处理之间的转换的主要内容,如果未能解决你的问题,请参考以下文章