我有一个包含两个字符串类型列的表(username, friend)
,对于每个用户名,我希望将它的所有朋友收集在一行上,并以字符串的形式连接起来。例如:('username1', 'friends1, friends2, friends3')
我知道MySQL和GROUP_CONCAT
就是这么做的。有没有办法用Spark SQL做到这一点?
发布于 2016-02-16 17:24:02
您可以尝试使用collect_list函数
sqlContext.sql("select A, collect_list(B), collect_list(C) from Table1 group by A
或者您可以注册UDF,如下所示
sqlContext.udf.register("myzip",(a:Long,b:Long)=>(a+","+b))
您可以在查询中使用此函数
sqlConttext.sql("select A,collect_list(myzip(B,C)) from tbl group by A")
发布于 2019-12-25 03:23:24
在Spark 2.4+中,这在collect_list()
和array_join()
的帮助下变得更加简单。
下面是一个用PySpark编写的演示,不过代码应该与Scala非常相似:
from pyspark.sql.functions import array_join, collect_list
friends = spark.createDataFrame(
[
('jacques', 'nicolas'),
('jacques', 'georges'),
('jacques', 'francois'),
('bob', 'amelie'),
('bob', 'zoe'),
],
schema=['username', 'friend'],
)
(
friends
.orderBy('friend', ascending=False)
.groupBy('username')
.agg(
array_join(
collect_list('friend'),
delimiter=', ',
).alias('friends')
)
.show(truncate=False)
)
输出:
+--------+--------------------------+
|username|friends |
+--------+--------------------------+
|jacques |nicolas, georges, francois|
|bob |zoe, amelie |
+--------+--------------------------+
这类似于MySQL的GROUP_CONCAT()
和Redshift的LISTAGG()
。
发布于 2018-04-07 01:49:57
下面是您可以在PySpark中使用的函数:
import pyspark.sql.functions as F
def group_concat(col, distinct=False, sep=','):
if distinct:
collect = F.collect_set(col.cast(StringType()))
else:
collect = F.collect_list(col.cast(StringType()))
return F.concat_ws(sep, collect)
table.groupby('username').agg(F.group_concat('friends').alias('friends'))
在SQL中:
select username, concat_ws(',', collect_list(friends)) as friends
from table
group by username
https://stackoverflow.com/questions/31640729
复制相似问题