根据列值将一行拆分为多行
Posted
技术标签:
【中文标题】根据列值将一行拆分为多行【英文标题】:Split a row into multiple rows based on a column value 【发布时间】:2019-04-25 17:20:17 【问题描述】:我正在尝试根据列值将表中的记录拆分为 2 条记录。输入表显示 3 种类型的产品及其价格。对于特定的产品(行),只有其对应的列才有价值。其他列有 Null。
我的要求是 - 每当产品列值(在一行中)是复合的(即有多个产品,例如 Bolt + Brush)时,记录必须分成两行 - 对于复合产品类型,每行 1 行.
因此,在此示例中,请注意第二行(在输入中)如何分成 2 行 -> 1 行用于“Bolt”,另一行用于“Brush”,它们的价格从相应的列中提取(即在这种情况下,“螺栓”= 3.99 美元,“刷子”= 6.99 美元)
注意:对于复合产品值,最多可以有 2 个产品,如本例所示(例如螺栓 + 刷子)
CustId | Product | Hammer | Bolt | Brush
--------------------------------
12345 | Hammer | $5.99 | Null | Null
53762 | **Bolt+Brush** | Null | $3.99 | $4.99
43883 | Brush | Null | Null | $4.99
我尝试使用 CTE 通过 UNION ALL 创建 2 条预定记录,然后使用 CTE 创建 main_table Left Outer Join,以便连接产生 2 条记录。
#CustId | Product | Price #
12345 | Hammer | $5.99
**53762** | **Bolt** | $3.99
**53762** | **Brush** | $4.99
43883 | Brush | $4.99
这只能通过 Spark-SQL 解决。
【问题讨论】:
如果相关产品在 Product 列中,那么各种 Price 列是否只有一个非空值?如果是这样,您也许可以设计一个 3 阶段的 UNION 语句;一个阶段 HAMMER 不为空,一个阶段 BOLT 不为空,一个阶段 BRUSH 不为空。 【参考方案1】:我认为这会奏效:
select CustId, 'Hammer' as product, Hammer
from t
where Product like '%Hammer%'
union all
select CustId, 'Bolt' as product, Bolt
from t
where Product like '%Bolt%'
union all
select CustId, 'Brush' as product, Brush
from t
where Product like '%Brush%';
【讨论】:
【参考方案2】:这也可以
select custid, product,
case when product like '%Hammer%' then hammer
when product like '%Bolt%' then bolt
else brush end as Price from
(select custid, explode(split(product,'\\+')) as product, hammer, bolt, brush
from t) x;
【讨论】:
完美运行以上是关于根据列值将一行拆分为多行的主要内容,如果未能解决你的问题,请参考以下文章