【问题标题】:Postgres aggregate json function to return array of objects with subqueryPostgres 聚合 json 函数以返回带有子查询的对象数组
【发布时间】:2023-02-10 20:16:53
【问题描述】:

我有 3 个表:patient、patient_form(连接表),如下所示:

病人

| id  | name                |
| --- | ------------------- |
| 1   | Bob                 |
| 2   | Matilda             |

patient_form(连接表)

| id  | patient_id | form_id |
| --- | ---------- | -------
| 1   | 1          |1
| 2   | 2          |1

形式

| id  | label
| --- | ------------------- |
| 1   | intake              |
| 1   | follow up           |

我想创建一个查询来选择患者并链接关系数据以产生以下输出:

{
 id: 1,
 name: "Bob",
 forms: [ {label: "intake"}, {label:"followup"} ]
}

我知道有一种方法可以使用 json_agg 来创建所需的对象数组,不幸的是我无法让它工作。

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    我使用json_build_object 得出如下结论:

    SELECT 
    ARRAY(
        SELECT json_build_object(
            'link', link, 
            'label', (SELECT label FROM form WHERE id = form_id))
        FROM patient_form
        WHERE patient_form.patient_id = patient.id
        ) AS "forms"
    WHERE patient.id = 1;
    

    【讨论】:

      【解决方案2】:

      您可以使用JOIN 代替forms 的子查询。完整实现如下:

      模式(PostgreSQL v15)

      CREATE TABLE IF NOT EXISTS patient ( 
        id INT NOT NULL PRIMARY KEY, 
        name TEXT NOT NULL 
      );
      CREATE TABLE IF NOT EXISTS form ( 
        id INT NOT NULL PRIMARY KEY, 
        label TEXT NOT NULL 
      );
      CREATE TABLE IF NOT EXISTS patient_form( 
        id INT NOT NULL PRIMARY KEY, 
        patient_id INT, 
        form_id INT,
        CONSTRAINT patient_id_fk FOREIGN KEY(patient_id)
              REFERENCES patient(id)
              ON DELETE CASCADE,
        CONSTRAINT form_id_fk FOREIGN KEY(form_id)
              REFERENCES form(id)
              ON DELETE CASCADE
      );
      INSERT INTO form(id, label) VALUES (1, 'intake'), (2, 'follow up');
      INSERT INTO patient(id, name) VALUES (1, 'Bob'), (2, 'Matilda');
      INSERT INTO patient_form(id, patient_id, form_id) VALUES (1, 1, 1), (2, 2, 1);
      

      查询#1

      SELECT json_build_object(
        'id', p.id,
        'name', p.name,
        'forms', json_agg(f)
      ) AS data
      FROM patient AS p
      JOIN patient_form AS p_f ON p_f.patient_id = p.id
      JOIN form AS f ON f.id = p_f.form_id
      WHERE p.id = 1
      GROUP BY p.id;
      
      data
      {"id":1,"name":"Bob","forms":[{"id":1,"label":"intake"}]}

      简单地说,输出是:

      {
        "id": 1,
        "name": "Bob",
        "forms": [
          {
            "id": 1,
            "label": "intake"
          }
        ]
      }
      

      View on DB Fiddle

      【讨论】:

        猜你喜欢
        • 2015-06-16
        • 2021-12-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-27
        • 1970-01-01
        相关资源
        最近更新 更多