【问题标题】:How to join 2 tables and have a list of other table's values nested in the first one in PostgreSQL?如何连接 2 个表并在 PostgreSQL 的第一个表中嵌套其他表的值列表?
【发布时间】:2021-07-05 17:06:21
【问题描述】:

假设我们有这 2 个表:person 和 car

CREATE TABLE person (
    id BIGSERIAL NOT NULL PRIMARY KEY,
    name VARCHAR NOT NULL
);
CREATE TABLE car (
    id BIGSERIAL NOT NULL PRIMARY KEY,
    make VARCHAR NOT NULL,
    person_id BIGINT NOT NULL REFERENCES person(id)
);

我试图做的是找到所有人,找到每辆车并创建一个像这样的对象数组

[
    {
        "id": "PERSON_ID",
        "name": "PERSON_NAME",
        "cars": [
            {
                "id": "CAR_ID",
                "model": "MODEL_NAME",
                "person_id": "PERSON_ID"
            }
        ]
    }
]

我尝试在car 表中的person 表上使用AS 别名和JOIN,但它不起作用。有没有办法做到这一点?谢谢!

【问题讨论】:

    标签: sql postgresql relationship


    【解决方案1】:

    您可以尝试以下方法。看到一个工作小提琴:

    架构 (PostgreSQL v13)

    CREATE TABLE person (
        id BIGSERIAL NOT NULL PRIMARY KEY,
        name VARCHAR NOT NULL
    );
    
    CREATE TABLE car (
        id BIGSERIAL NOT NULL PRIMARY KEY,
        make VARCHAR NOT NULL,
        person_id BIGINT NOT NULL REFERENCES person(id)
    );
    
    insert into person(name) values ('tom'),('harry');
    
    insert into car (id,make,person_id) values (1,'ford',1),(2,'audi',1),(3,'nissan',2);
    

    查询 #1

    SELECT
       p.id,
       p.name,
       array_agg(row_to_json(c)) cars
    FROM
       person p
    INNER JOIN
       (SELECT id, make model, person_id FROM car) c ON p.id = c.person_id
    GROUP BY
       p.id,
       p.name;
    
    id name cars
    1 tom [{"id":1,"model":"ford","person_id":1},{"id":2,"model":"audi","person_id":1}]
    2 harry [{"id":3,"model":"nissan","person_id":2}]

    View on DB Fiddle

    【讨论】:

    • 您好,感谢您的回答!它工作正常!顺便说一句,如果你不介意,你能不能给我这样的例子,但只是为了一个对象?就像一列有另一列但只有一个。不是数组。我是初学者,刚刚完成了 4 小时的课程。只是想弄脏我的手。干杯!
    • 您能否在另一个问题中进一步澄清?你是什​​么意思一列有另一列?一个对象是否意味着一行?
    • 当然,我想实现这样的目标:pastebin.com/cpmaYgV6
    • @xyz1888 看看这个小提琴db-fiddle.com/f/5izpFv5YVUD2gKYgCDGgsu/1
    • 非常感谢!
    【解决方案2】:

    如果你想在 Postgres 中将结果集作为一个数组,你可以使用:

    select p.*, array_agg(c)
    from person p join
         car c
         on c.person_id = p.id
    group by p.id;
    

    如果你也想返回 JSON,你可以做类似的事情。

    【讨论】:

    • 我也尝试过array_agg(c),但示例结果生成了{"(1,ford,1)","(2,audi,1)"} 一个看似字符串元组的数组。见小提琴:dbfiddle.uk/…
    • @ggordon 。 . .这些不是真正的字符串。这就是 Postgres 表示记录值的方式。您仍然可以访问元素和字段:dbfiddle.uk/…
    • 您好,感谢您的回答!按预期工作!如果可以的话,我会赞成这个答案和@ggordon 的答案。
    • 感谢@GordonLinoff。这很有启发性
    猜你喜欢
    • 2012-06-22
    • 2020-05-17
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多