在 Join PostgreSQL 中取消嵌套数组

Posted

技术标签:

【中文标题】在 Join PostgreSQL 中取消嵌套数组【英文标题】:Unnesting array with in Join PostgreSQL 【发布时间】:2022-01-13 01:40:57 【问题描述】:

我有两个表,其中一个有一个唯一的 ID 列和一个包含数组的列,这些数组包含表 B 中唯一记录的零个或多个标识符。我试图显示每个项目的使用顺序,但是我无法想办法将表 A 和 B 连接起来,这样不仅每个订单或项目都有一行,而且所有订单上都有尽可能多的项目

表 A:

OrderID   |      Items       |      name
----------+------------------+------------
order1    | item1,item2    |  "Bob's pizza order"
order2    | item3,item1    |  "Alice's breakfast order"

表 B:

itemID   |      price     |      name
---------+----------------+------------
item1    |      2.95      |  "cheese"
item2    |      3.15      |  "tomato sauce"
item3    |      3.50      |  "eggs"

期望的输出类似于

ItemID   |     OrderID    |     name
---------+----------------+------------
item1    |     order1     |  "cheese"
item1    |     order2     |  "cheese"
item2    |     order1     |  "tomato sauce"
item3    |     order2     |  "eggs"

有谁知道如何取消表 A 中的数组的嵌套,以便我可以使用所有项目将 A 和 B 与每个订单的每个项目的记录连接起来?

【问题讨论】:

你可以阅读这篇文章:***.com/questions/2486725/… 更好的解决方案是正确规范您的数据模型。如果您需要定期取消嵌套数组,这强烈表明选择去规范化不是一个好的选择。 【参考方案1】:

看起来 postgresSQL 有一些我不习惯的很棒的功能!

查看其他文档后,这可能会达到您正在寻找的效果 -

with table_a (OrderID, Items) as
      (select 'order1', 'item1,item2,item4' union all
       select 'order2', 'item3,item1'
    )
,

trim as (
  select OrderID, Replace(Replace(Items, '', ''),'','') as Items
from table_a)

SELECT
OrderID,
unnest(string_to_array(Items, ',')) AS ItemID
from trim

如果 Items 列是一个真正的数组,您应该能够移除 trim CTE 并移除 string_to_array 函数。

整个事情可能看起来像 -

with unnested_data as(
SELECT
 OrderID,
 unnest(Items) AS ItemID
FROM table_a)

SELECT
 a.ItemID,
 a.OrderID,
 b.name
FROM unnested_data AS a
JOIN table_b AS b
 on a.ItemID = b.itemID

【讨论】:

【参考方案2】:

要将每个项目作为一行,您需要取消嵌套数组(本质上是动态规范化模型):

select b.itemid, a.orderid, b.name
from table_a a 
  cross join unnest(a.items) as i(item) 
  join table_b b on i.item = b.itemid
order by b.itemid;

Online example

【讨论】:

谢谢,这很简洁,而且效果很好——交叉连接对我来说是新的,所以我从中学到了很多!也感谢您制作演示!

以上是关于在 Join PostgreSQL 中取消嵌套数组的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL:更新JSONB结构中嵌套数组中元素的属性

使用 PostgreSQL/NodeJS 获取 JOIN 表作为结果数组

如何在 PostgreSQL JSONB 列中查询具有异构元素的嵌套数组

在JS中取消嵌套对象数组

是否可以在 BigQuery 中取消嵌套数组,以便将嵌套数据按键值拆分为列?

如何在 BigQuery 标准 SQL 中取消嵌套多个数组