首页 > 解决方案 > Postgresql - 使用一个表中的选定列作为 json 选择语句

问题描述

https://www.db-fiddle.com/f/gZXz9hJRzpiEmDr7V8PXEG/0

PostgreSQL 10.x

考虑下表:

CREATE TABLE attributes (
    attr TEXT
);

INSERT INTO attributes VALUES('sth1');
INSERT INTO attributes VALUES('sth2');

CREATE TABLE items (
    name TEXT,
    custom JSONB
);

INSERT INTO items VALUES ('A', '{"sth1": "Hello"}');
INSERT INTO items VALUES ('B', '{"sth1": "Hello", "sth2": "Okay"}');
INSERT INTO items VALUES ('C', '{"sthNOT": "Hello", "sth2": "Okay"}');

我的目标是仅将attributes表中的列作为列中的 Json 键ìtems.custom查询 - 因此查询始终返回相同的键集。

当我知道我会做的列时:

SELECT name, custom->>'sth1', custom->>'sth2' FROM items;

我想让这个查询“动态” - 所以attributes表中可以有任意键定义。

我也可以在查询中创建一个新的 Json 对象 - 仅包含表中定义的键和列attributes中的相应值items.custom。因此,将一个从 中创建的 Json 对象attributesitems.custom数据合并是一种选择。

有没有办法在 Postgres 中实现这一点?

标签: jsonpostgresqljsonb

解决方案


您需要一个函数来动态格式化和执行合适的查询。该函数返回带有namejsonb 对象的行data

create or replace function select_from_items()
returns table(name text, data jsonb) language plpgsql as $$
declare
    cols text;
begin
    select string_agg(format('%1$L, custom->>%1$L', attr), ', ')
    from attributes
    into cols;

    return query execute format('
        select name, jsonb_strip_nulls(jsonb_build_object(%s)) 
        from items', cols);
end $$;

select * from select_from_items();

 name |               data                
------+-----------------------------------
 A    | {"sth1": "Hello"}
 B    | {"sth1": "Hello", "sth2": "Okay"}
 C    | {"sth2": "Okay"}
(3 rows)

因此,这是您的第二选择。第一个假设创建一种数据透视表并且需要更复杂的技术,例如


推荐阅读