如何使用 sql 在数据块上创建带有嵌套映射的表

Posted

技术标签:

【中文标题】如何使用 sql 在数据块上创建带有嵌套映射的表【英文标题】:How to create table with nested map on databricks using sql 【发布时间】:2021-04-09 19:29:19 【问题描述】:

我正在尝试复制这个给定的架构:

+---------------+-----------------------------------------------------------------------+
| column        | type                                                                  |
+---------------+-----------------------------------------------------------------------+
| first_name    | STRING                                                                |
| last_name     | STRING                                                                |
| subscriptions | MAP<STRING, MAP <titles:ARRAY<STRING>, payment_methods:ARRAY<STRING>> |

有了这个声明:

CREATE TABLE IF NOT EXISTS mydb.map1 (
  first_name STRING,
  last_name STRING,
  subscriptions MAP < MAP < STRING, ARRAY<STRING> >,  MAP < STRING, ARRAY<STRING> >> 
)

我设法编写了这个架构。但老实说,我不能 100% 确定它是否反映了给定模式。我很困惑的是这部分:“MAP 标题:ARRAY

+---------------+----------------------------------------------------------+ 
| col_name      | data_type                                                | 
+---------------+----------------------------------------------------------+
| first_name    | string                                                   | 
| last_name     | string                                                   | 
| subscriptions | map<map<string,array<string>>,map<string,array<string>>> |

# Partitioning
Not partitioned

所以我尝试用这个插入语句来测试它:

%sql
INSERT INTO
  mydb.map1
VALUES  
  ('String1', 'String2', Map( Map('titles', Array('S1', 'S2', 'S3')), Map('payment_methods', Array('S1', 'S2', 'S3'))))

但这只是给了我这个错误声明,我在这里卡住了:

Error in SQL statement: AnalysisException: cannot resolve 'map(map('titles', array('S1', 'S2', 'S3')), map('payment_methods', array('S1', 'S2', 'S3')))' due to data type mismatch: The key of map cannot be/contain map.; line 9 pos 2;

我必须如何编写 CREATE 语句才能获得上述给定的架构?

【问题讨论】:

【参考方案1】:

坦率地说,您的创建表并不完全正确。我不明白 subscriptions 字段 MAP&lt;STRING, MAP &lt;titles:ARRAY&lt;STRING&gt;, payment_methods:ARRAY&lt;STRING&gt;&gt; 的定义如何在映射中命名字段 - 根据定义,映射支持任意键,而不仅仅是特定键。

如果您想实现这一点,那么最好使用struct 作为地图的值,请尝试以下操作:

subscriptions MAP<STRING, STRUCT<titles:ARRAY<STRING>, payment_methods:ARRAY<STRING>>>

真正的问题是您声明了一个键和值都是映射的映射。如果你还想使用地图,那么你需要声明如下:

subscriptions MAP<STRING, MAP<STRING, ARRAY<STRING>>>

【讨论】:

以上是关于如何使用 sql 在数据块上创建带有嵌套映射的表的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spark SQL 在 Parquet 文件中选择嵌套数组和映射

ORACle中对于数据量庞大的表如何用delete+insert来代替update语句操作步骤或者请举例说明

使用颤振文档在每个视图图块上创建带有心形图标的随机单词列表视图。 (请在下面找到问题)

使用 kable() 格式化带有嵌套列的表

在数据块上运行 sql 查询时出现不匹配错误

如何在 Spring Boot 中将嵌套的 JSON 对象映射为 SQL 表行