假设我们有一个Posterre表
CREATE TABLE staging_book (
book_id int4 NULL,
authors jsonb NULL
);
字符串
每个authors字段的值都是一个字符串数组。
第一行如下所示。
| 作者| authors |
| ------------| ------------ |
| 第一个月| ["Kafka, Franz", "Feynman, Richard", "Pratchett, Terry"]
|
| ["Tolkien, JRR", "Tolkien, C"]
个| ["Tolkien, JRR", "Tolkien, C"]
|
我们将其分解为标准化的表,并将作者放在单独的表中。
我们想生成这个,这样就可以将它插入到一个单独的表中。
| 作者| author |
| --| ------------ |
| Kafka| Kafka, Franz |
| 费曼<英>来华传教士。| Feynman, Richard |
| 特里·普拉切特| Pratchett, Terry |
| 托尔金,JRR| Tolkien, JRR |
| 托尔金角| Tolkien, C |
交叉联接是不行的。这
SELECT s.work_id, a.author
FROM stagework s
CROSS JOIN LATERAL jsonb_array_elements_text(s.authors) AS a(author);
型
将匹配每一个作者的每一个作品,这是 * 显然 * 不正确的,完全没有解决的要求,明确说明在标题。
用一个单独的应用程序来枚举行并解析json,这在逻辑上是微不足道的,但要处理三千万行,这将是一种低效的方式。
我找到了jsonb_array_elements_text
函数,但我不知道如何将值与结果行中的work_id
键相匹配。这可以直接在SQL中完成吗?
这似乎是相关的Convert jsonb key value to key value array
我很清楚作者和作品之间是一种多对多的关系。在我开始删除冗余之前,还有很多无用的数据需要修复。
1条答案
按热度按时间ohtdti5x1#
这个[交叉连接横向]将匹配每个作者的每一个工作,这显然是不正确的,完全没有解决的要求,明确说明在标题中。
不。它完全符合你的要求。注意
LATERAL
关键字--它意味着函数将对左关系的每一行执行,并且仅针对该行进行连接。Try it!