【问题标题】:How to SELECT rows in an order dictated by a JSONB array of primary key IDs?如何按主键 ID 的 JSONB 数组指定的顺序选择行?
【发布时间】:2020-09-23 16:40:00
【问题描述】:

这是我的虚拟设置:

CREATE TABLE containers (
    id SERIAL PRIMARY KEY,
    positions jsonb
);
CREATE TABLE bits (
    id SERIAL PRIMARY KEY,
    container_id integer REFERENCES containers(id) ON DELETE CASCADE ON UPDATE CASCADE,
    data jsonb
);

containers 中的示例行:

id  positions
1   [4, 2, 3]

我想要完成的是使用containers 中的positions 来指示返回位的顺序。这似乎比在bits 中使用具有0、1、2、3 等值的smallint position 列更容易,并且必须在用户重新排序位时全部更新。

本质上,我想做的是在ORDER BY 中使用positions 数组,例如(伪代码):

SELECT b.id, b.data FROM bits b, container c WHERE b.container_id = 1 ORDER BY (jsonb_array_elements(c.positions));

期望的输出是:

id  data
4   {"banner": "This is a message!"}
2   {"name": "Bob"}
3   {"playlistId": 3}

我该如何做到这一点?我正在使用 Postgres 10.7。

【问题讨论】:

    标签: arrays json postgresql sql-order-by postgresql-10


    【解决方案1】:

    您需要使用jsonb 函数来执行此操作。

    请尝试以下方法:

    select b.*
      from bits b
           join containers c
             on c.id = b.container_id
           join lateral jsonb_array_elements_text(c.positions) 
                          with ordinality as p(id, rn)
             on p.id::int = b.id
     where b.container_id = 1
     order by p.rn::int
    

    【讨论】:

    • 这会以错误的顺序返回位(2、3、4 - 而不是预期的 4、2、3)。
    • 啊,只需要更改ORDER 子句:ORDER BY p.rn::int
    • 希望你不介意,我对你的回答做了一个小的修改,这样它更适合这个问题,对其他人来说更清楚。
    • @ffxsam 一点也不。我不知道您是否希望 container_id 对输出中的行进行分组。这就是导致我使用b.id 的第一个错误的原因。祝你的项目好运!
    • 谢谢,帮了大忙!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多