【问题标题】:Postgresql: select rows by OR condition - including going through json arrayPostgresql:按 OR 条件选择行 - 包括通过 json 数组
【发布时间】:2020-05-26 02:19:38
【问题描述】:

我有一个通过以下查询创建的表:

create table data
(
    id integer not null unique,
    owner text,
    users jsonb not null
);

表格如下所示:

+----+-------+---------------------------------------------+
| id | owner |                    users                    |
+----+-------+---------------------------------------------+
|  1 | alice | []                                          |
|  2 | bob   | [{"accountId": "alice", "role": "manager"}] |
|  3 | john  | [{"accounId": "bob", "role": "guest"}]      |
+----+-------+---------------------------------------------+

我需要代表 Alice 获取第 1 行和第 2 行。

获取基于所有者的行非常完美:

SELECT *
FROM data
WHERE owner = 'alice'

获取基于 jsonb 的行虽然可以管理,但有点棘手:

SELECT *
FROM data, jsonb_array_elements(users) x
WHERE (x ->> 'accountId') = 'alice'

但是将它们放在一起得到的只是基于 jsonb 的:

SELECT *
FROM data, jsonb_array_elements(users) x
WHERE owner = 'alice' OR (x ->> 'accountId') = 'alice'

如何获得如下所示的选择?

+----+-------+---------------------------------------------+
| id | owner |                    users                    |
+----+-------+---------------------------------------------+
|  1 | alice | []                                          |
|  2 | bob   | [{"accountId": "alice", "role": "manager"}] |
+----+-------+---------------------------------------------+

如果我能得到一个看起来像这样的选择就更好了

+----+----------+
| id |   role   |
+----+----------+
|  1 | owner    |
|  2 | manager  |
+----+----------+

【问题讨论】:

    标签: sql arrays json postgresql where-clause


    【解决方案1】:

    问题在于空的 json 数组,当 cross joined 和 jsonb_array_elements() 时,它会从结果集中驱逐相应的行。相反,您可以创建一个left join lateral

    select d.*
    from data d
    left join lateral jsonb_array_elements(d.users) as x(js) on 1 = 1
    where 'alice' in (d.owner, x.js ->> 'accountId')
    

    请注意,如果您的数组始终包含 0 或 1 个元素,则您不需要横向连接 - 您的查询会更简单地表述为:

    select d.*
    from data d
    where 'alice' in (d.owner, d.data -> 0 ->> 'accountId')
    

    Demo on DB Fiddle - 两个查询都返回:

    编号 |所有者 |用户 -: | :---- | :-------------------------------------------- 1 |爱丽丝 | [] 2 |鲍勃 | [{“角色”:“经理”,“accountId”:“爱丽丝”}]

    【讨论】:

      猜你喜欢
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多