行列转换是数据处理中常见的操作,日常报表经常需要按照业务看数习惯做行列转换,因此,本文总结一下SQL行列转换的实现。

行列转换包括行转列和列转行:

  • 行转列:由行变成列,行变少列变多
  • 列转行:由列变成行,列变少行变多

假设我们有如下 table1 和 table2 两张汇总表(不重复),table1 → table2 即为行转列,table2 → table1 即为列转行,我们看一下Presto SQL行转列、列转行的实现。

table1 → table2 行转列:

--行转列_使用case when实现
select
	cust_id,
	sum(case when product = '水果' then amount end) as fruit,
	sum(case when product = '牛奶' then amount end) as milk,
	sum(case when product = '零食' then amount end) as snack
from table1
group by 1;


--行转列_使用map实现
select
	cust_id,
	kv['水果'] as fruit,
	kv['牛奶'] as milk,
	kv['零食'] as snack
from (
	select
		cust_id,
		map_agg(product, amount) as kv
	from table1
	group by 1
	);

table2 → table1 列转行:

--列转行_使用cross join unnest实现
select
	cust_id,
	product,
	amount
from table2
cross join unnest(
	array['fruit', 'milk', 'snack'],
	array[fruit, milk, snack]
	) as t (product, amount);

以上的行转列、列转行即是我们通常所说的行列转换,不过实际取数中还有一种”列转行”-将单行内容转成多行内容,这是因为源表在存储数据时将数据合并存储了。 假设我们有如下 table3 和 table4 两张表:

table3 → table4 单行转多行:

--单行转多行_使用cross join unnest实现
select
    cust_id,
    amount_split as amount
from table3
cross join unnest(split(amount, ',')) as t (amount_split);


对于业务固化的报表而言,无论是行转列还是列转行,都是必要的。但对于分析而言,多维度汇总表保留的信息量更多、伸缩性扩展性更强,在取数过程中,行转列是不必要的,列转行是必要的,我们可以在SQL中跑出多维度汇总的源表后,继续在Excel中或者在Python中做各种透视分析。


原创文章,欢迎转载,转载请注明出处并留下原文链接。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注