sql - 更新结构数组 - Spark
问题描述
我有以下 spark delta 表结构,
+---+------------------------------------------------------+
|id |addresses |
+---+------------------------------------------------------+
|1 |[{"Address":"ABC", "Street": "XXX"}, {"Address":"XYZ", "Street": "YYY"}]|
+---+------------------------------------------------------+
这里的地址列是一个结构数组。
我需要从“Street”属性值将数组内的第一个地址更新为“XXX”,而不更改列表中的第二个元素。
因此,“ABC”应更新为“XXX”,“XYZ”应更新为“YYY”
你可以假设,我在结构中有很多属性,比如街道、邮政编码等,所以我想让它们保持不变,只是从 Street 属性更新 Address 的值。
如何在 Spark、Databricks 或 Sql 中执行此操作?
架构,
|-- id: string (nullable = true)
|-- addresses: array (nullable = true)
| | | |-- element: struct (containsNull = true)
| | | | |-- Address: string (nullable = true)
| | | | |-- Street: string (nullable = true)
干杯!
解决方案
请检查以下代码。
scala> vdf.show(false)
+---+--------------+
|id |addresses |
+---+--------------+
|1 |[[ABC], [XYZ]]|
+---+--------------+
scala> vdf.printSchema
root
|-- id: integer (nullable = false)
|-- addresses: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- Address: string (nullable = true)
scala> val new_address = array(struct(lit("AAA").as("Address")))
scala> val except_first = array_except($"addresses",array($"addresses"(0)))
scala> val addresses = array_union(new_address,except_first).as("addresses")
scala> vdf.select($"id",addresses).select($"id",$"addresses",to_json($"addresses").as("json_addresses")).show(false)
+---+--------------+-------------------------------------+
|id |addresses |json_addresses |
+---+--------------+-------------------------------------+
|1 |[[AAA], [XYZ]]|[{"Address":"AAA"},{"Address":"XYZ"}]|
+---+--------------+-------------------------------------+
更新
scala> vdf.withColumn("addresses",explode($"addresses")).groupBy($"id").agg(collect_list(struct($"addresses.Street".as("Address"),$"addresses.Street")).as("addresses")).withColumn("json_data",to_json($"addresses")).show(false)
+---+------------------------+-------------------------------------------------------------------+
|id |addresses |json_data |
+---+------------------------+-------------------------------------------------------------------+
|1 |[[XXX, XXX], [YYY, YYY]]|[{"Address":"XXX","Street":"XXX"},{"Address":"YYY","Street":"YYY"}]|
+---+------------------------+-------------------------------------------------------------------+
推荐阅读
- r - HighcharteR:工具提示未显示正确的 x 轴值
- bluetooth - Raspberry PI BTLE 可以发现 Fitbit 和 Scale 设备,但无法配对
- asp.net-core - 如何使用目录名称中的句点从 Asp .Net Core 提供静态文件
- java - 当我运行 Maven 打包的 JAR 文件时出现 NoClassDefFoundError
- flutter - 如何在颤动的滚动视图中将容器或任何其他小部件固定在应用栏下方
- sql - 为什么会引发变异表错误?
- typescript - 为 puppeteer 页面的返回值键入断言。$eval 承诺
- javascript - 需要在表单验证中忽略引导模式验证
- javascript - Socket.IO 无法从服务器向客户端发送消息
- java - 如何在没有 NullPointerException 的情况下更改 JLabel 中显示的图像?