【问题标题】: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 不为空。

标签: sql apache-spark-sql


【解决方案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;
    

    【讨论】:

    • 完美运行
    猜你喜欢
    • 1970-01-01
    • 2016-04-10
    • 2023-04-01
    • 2020-02-10
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多