集合返回函数(json_array_elements)与表列的连接结果

Posted

技术标签:

【中文标题】集合返回函数(json_array_elements)与表列的连接结果【英文标题】:Join result of set-returning function (json_array_elements) with table column 【发布时间】:2015-12-03 23:42:41 【问题描述】:

假设我有两张桌子:

用户组合

+--------+----------------+
|   id   |   combination  |
+--------+----------------+
|    6   |     [1, 2]     |
|    9   |     [2, 3]     |
+--------+----------------+

颜色

+--------+----------------+
|   id   |   color        |
+--------+----------------+
|    1   |       Blue     |
|    2   |       Yellow   |
|    3   |       Green    |
+--------+----------------+

我正在尝试将 json_array_elements(color) 的结果与 Elements 的 id 结合起来。比如

的结果
select json_array_elements(color) as CombinationID
from User_Combination where id = 6;

+-------------------+
|   CombinationID   |
+-------------------+
|    1              |
|    2              |
+-------------------+

我无法通过Colors.id 加入CombinationID。当我尝试 SQL 命令时,例如:

select json_array_elements(article_data) AS articlesInOutfits (color) as CombinationID
from User_Combination uc JOIN Colors co ON co.id = articlesInOutfits;

select json_array_elements(article_data) AS articlesInOutfits (color) as CombinationID
from User_Combination uc JOIN Colors co ON co.id = uc.articlesInOutfits;

它说articlesInOutfits 不存在。 有什么建议吗?

【问题讨论】:

你的 Postgres 版本? 使用 9.3.3。令人惊讶的是,unnest 不起作用。 您能解决问题中的一些令人困惑的错误吗? json_array_elements(color) ? Elements 指的是什么?显示数据类型和约束的实际表定义会更有用。 可惜你没有Postgres 9.4,里面引入了json_array_elements_text():dba.stackexchange.com/a/54289/3684这样会更方便。但是,当您坚持使用 Postgres 9.3 时,at least uprgrade to the latest point release。你的已经过时了。 感谢您的提示,欧文!会的。 【参考方案1】:

使用unnest() 获得解包组合:

select id, unnest(combination) cid
from user_combination;

 id | cid 
----+-----
  6 |   1
  6 |   2
  9 |   2
  9 |   3
(4 rows)    

使用 unpacked cids 加入 colors

select u.id, color
from (
    select id, unnest(combination) cid
    from user_combination
    ) u
join colors c
on cid = c.id;

 id | color  
----+--------
  6 | Blue
  6 | Yellow
  9 | Yellow
  9 | Green
(4 rows)

使用聚合函数(例如json_agg())为用户聚合颜色:

select u.id, json_agg(color)
from (
    select id, unnest(combination) cid
    from user_combination
    ) u
join colors c
on cid = c.id
group by 1;

 id |      json_agg       
----+---------------------
  9 | ["Yellow", "Green"]
  6 | ["Blue", "Yellow"]
(2 rows)    

如果combination 的类型是json,您应该在横向连接中使用json_array_elements()

select u.id, json_agg(color)
from (
    select id, cid
    from user_combination,
    lateral json_array_elements(combination) cid
    ) u 
join colors c
on cid::text::int = c.id
group by 1;

【讨论】:

太棒了,等一下我试试 我正在使用 Postgres 版本 9.3.3,它说:错误:函数 unnest(json) 不存在 啊,我明白了,我将数组存储为 json 类型。我会解决这个问题,然后尝试 unnest 我假设combination 的类型是int[]。对于json,您应该在编辑后的答案中使用json_array_elements 你是个野兽。非常感谢您的帮助!

以上是关于集合返回函数(json_array_elements)与表列的连接结果的主要内容,如果未能解决你的问题,请参考以下文章

在 django 的测试中找不到 Postgres 函数 json_array_elements

具有空值的 json_array_elements

Postgresql json_array_elements

C#怎么定义泛型集合类型的函数,返回一个集合

过滤集合返回函数结果

SELECT 子句中多个集合返回函数的预期行为是啥?