繁体   English   中英

如何从 Spark SQL 中的逗号分隔字符串中删除重复项?

[英]How to Remove Duplicates from Comma seperated string in Spark SQL?

这是我的数据集的示例。 我想编写 Spark SQL 来将具有重复值的项目列表更改为唯一值,因此例如“苹果,香蕉,香蕉”将变为“苹果,香蕉”,我在这里编写了代码:

SELECT  ItemId, Date, concat_ws(',',collect_set(CAST(SPLIT(PointNameArray, ','),ARRAY<STRING>))) AS VarN
FROM    dataset 

但我不断收到错误说明

由于数据类型不匹配,无法解析 'concat_ws(',', collect_set(split( PointNameArray , ',')))':参数 2 需要(数组或字符串)类型,但是,'collect_set(split( PointNameArray , ','))' 是 array<array>

在此处输入图片说明

itemlist 的结果是

apple, banana
phone, computer
table, chair

所以表格应该是这样的

在此处输入图片说明

你收到错误:

由于数据类型不匹配,无法解析 'concat_ws(',', collect_set(split(dataset.PointNameArray, ',')))':参数 2 需要(数组或字符串)类型,但是,'collect_set(split(dataset.PointNameArray, ',')))' , ','))' 是数组

因为split已经返回一个array<string>并且collect_set将整个数组视为集合中的单个条目,因此array<array<string>>

需要注意的是collect_set是一个聚合函数,可以在 group by 中应用,也可以作为每行的窗口函数。 然而,将它作为窗口函数应用在每一行上会冒整个拆分数组被视为一个不是目标的元素的风险。

此外,当您按 , split一些样本数据( 'apple, banana, banana, ,有些可能会有空格( )之前的值和banana是从不同的banana 为了确保我们有独特的价值,我们可以trim这些。

由于您使用的是 spark sql,下面的示例将使用 spark-sql 而不是 python/scala apis,后者可以遵循相同的方法

之前的示例数据框

+------+----------+---------------------+
|ItemId|Date      |itemList             |
+------+----------+---------------------+
|item1 |2019-01-01|apple, banana, banana|
+------+----------+---------------------+

拟议守则

SELECT  
    ItemId, 
    Date, 
    concat_ws(',',collect_set(trim(isplit))) as VarN
FROM
    df
LATERAL VIEW explode(SPLIT(itemList,',')) as isplit
GROUP BY ItemId, Date

输出之后

+------+----------+------------+
|ItemId|Date      |VarN        |
+------+----------+------------+
|item1 |2019-01-01|apple,banana|
+------+----------+------------+

在上面的示例代码中,数据是:

  1. Split by ,使用SPLIT(itemList,',')
  2. 在横向视图输出中使用explode(SPLIT(itemList,','))分解为多行
+------+----------+-------+
|ItemId|Date      |isplit |
+------+----------+-------+
|item1 |2019-01-01|apple  |
|item1 |2019-01-01| banana|
|item1 |2019-01-01| banana|
+------+----------+-------+
  1. 然后使用trim(isplit)修剪数据以删除空格
  2. 然后我们使用collect_set聚合数据,它将提供我们的唯一值,在其他列ItemId, Date上分组。 注意。 如果你有很多列,你可以在唯一的列上分组,例如ItemId并简单地在其他列上使用MAX ,例如
SELECT  
    ItemId, 
    MAX(Date) as Date, 
    concat_ws(',',collect_set(trim(isplit))) as VarN
FROM
    df
LATERAL VIEW explode(SPLIT(itemList,',')) as isplit
GROUP BY ItemId
  1. 最后我们使用concat_ws连接这些值

我认为您想使用array_distinct函数而不是collect_set

spark.sql("""
SELECT  ItemId, 
        Date, 
        PointNameArray,
        concat_ws(',',array_distinct(split(PointNameArray, ','))) AS VarN
FROM    dataset
""").show(truncate=False)

#+------+----------+-------------------------+--------------+
#|ItemId|Date      |PointNameArray           |VarN          |
#+------+----------+-------------------------+--------------+
#|item1 |2019-01-01|apple,banana,apple,banana|apple,banana  |
#|item2 |2019-01-01|phone,computer,computer  |phone,computer|
#|item3 |2019-01-01|table,chair,table,chair  |table,chair   |
#+------+----------+-------------------------+--------------+

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM