PostgreSQL和嵌套的json对象

时间:2017-04-18 09:38:59

标签: json postgresql

我需要在这样的结构中构建json对象:

{
    "id":1, 
    "name": "Jessica", //other top-level key-values
    "add_info": {
        "first_object":{"date":"2017-04-17","id":1},
        "second_object":{"date":"2017-04-17","id":1} //etc.
    }
}

不幸的是,我对那些大量但没有示例的PostgreSQL json函数感到困惑,并且无法弄清楚如何更好地实现这一目标。 我试过这个:

SELECT row_to_json(t, TRUE)
FROM (
       SELECT
         id, name
         , (
             (
               SELECT row_to_json(b) AS first_object
               FROM (
                      SELECT *
                      FROM table1
                      WHERE client_id = 1
                    ) b
             ),
             (
               SELECT row_to_json(b) AS second_object
               FROM (
                      SELECT *
                      FROM table2
                      WHERE client_id = 1
                    ) b
             )
           ) AS add_info

       FROM main_table
       WHERE id = 1
     ) t;

但我得到了这个:

{
    "id":1, 
    "name": "Jessica", //other top-level key-values
    "add_info": {
        "f1":{"date":"2017-04-17","id":1},
        "f2":{"date":"2017-04-17","id":1} //etc.
    }
}

f1,f2 !! Whaat ??!

似乎我可以做点什么来给他们起名字:

SELECT row_to_json(t, TRUE)
FROM (
       SELECT
         id, name
         , (
             (SELECT row_to_json(first_row) first_row
              FROM
                (
                  SELECT row_to_json(b) AS first_object
                  FROM (
                         SELECT *
                         FROM first_table
                         WHERE client_id = 1
                       ) b
                ) AS first_row
             ),
             (SELECT row_to_json(second_row) second_row
              FROM
                (
                  SELECT row_to_json(b) AS second_object
                  FROM (
                         SELECT *
                         FROM second_table
                         WHERE client_id = 1
                       ) b
                ) AS second_row
             )
           ) AS add_info

       FROM main_table
       WHERE id = 1
     ) t;

但这会产生一个额外的对象:

{
    "id":1,
    "name":"CRED", 
    "add_info":{
        "f1":{"first_object":{"date":"2017-04-17","id":1}},
        "f2":{"second_object":{"date":"2017-04-17","id":1}}
    }
}

我能解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

您可以使用公用表表达式:

WITH add_info(first_object, second_object) AS
     (SELECT
        (SELECT row_to_json(table1)
                FROM table1
                WHERE id = 1
        ),
        (SELECT row_to_json(table2)
                FROM table2
                WHERE id = 1
        )
     )
SELECT row_to_json(t, TRUE)
FROM (
       SELECT
         id, name, add_info
       FROM main_table CROSS JOIN add_info
       WHERE id = 1
     ) t;