在 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 列中查询具有异构元素的嵌套数组