使用自联接在row_to_json()中复制JSON元素

时间:2017-04-06 09:08:02

标签: sql postgresql postgresql-9.2 sjson

这是对这个优秀问答的后续行动:13227142

我几乎必须做同样的事情(使用PostgreSQL 9.2的约束),但我只使用一个表。因此,查询使用自联接(为了生成正确的JSON格式),这会导致重复的 id 字段。我怎么能避免这个?

示例:

CREATE TABLE books
(
  id serial primary key,
  isbn text,
  author text,
  title text,
  edition text,
  teaser text
);

SELECT row_to_json(row)
FROM
(
  SELECT id AS bookid,
  author,
  cover
  FROM books
  INNER JOIN 
  (
    SELECT id, title, edition, teaser
    FROM books
  ) cover(id, title, edition, teaser)
  USING (id)
) row;

结果:

{
  "bookid": 1,
  "author": "Bjarne Stroustrup",
  "cover": {
    "id": 1,
    "title": "Design and Evolution of C++",
    "edition": "1st edition",
    "teaser": "This book focuses on the principles, processes and decisions made during the development of the C++ programming language"
  }
}

我想摆脱" id"在"封面"。

3 个答案:

答案 0 :(得分:1)

您需要ID才能加入,因此如果没有ID,您就无法进行此类简短查询。你需要构建它。 Smth喜欢:

select row_to_json(row,true)
FROM
(
with a as (select id,isbn,author,row_to_json((title,edition,teaser)) r from books
)
select a.id AS bookid,a.author, concat('{"title":',r->'f1',',"edition":',r->'f2',',"teaser":',r->'f3','}')::json as cover
  from a
) row;
                      row_to_json
--------------------------------------------------------
 {"bookid":1,                                          +
  "author":"\"b\"",                                    +
  "cover":{"title":"c","edition":"d","teaser":"\"b\""}}
(1 row)

如果没有加入,您可以使用两倍的资源

答案 1 :(得分:1)

这结果是一个棘手的任务。据我所知,通过简单的查询无法实现。 一种解决方案是使用预定义的数据类型:

CREATE TYPE bookcovertype AS (title text, edition text, teaser text);

SELECT row_to_json(row)
FROM
(
  SELECT books.id AS bookid, books.author, 
    row_to_json(row(books.title, books.edition, books.teaser)::bookcovertype) as cover
  FROM books
) row;

答案 2 :(得分:0)

为了完整起见,我自己偶然发现了另一个答案:字符串函数可以消除其他字段。但是,我更喜欢 AlexM 的anwer,因为它会更快,并且仍然与PostgreSQL 9.2兼容。

<?php
    $stock = array(
                array(
                        "Dated" => "2017-04-01",
                        "Nadeem" => 1995,
                        "NadeemKaat" => 40,
                        "Ali" => 0,
                        "AliKaat" => 0,
                        "Usman" => 0,
                        "UsmanKaat" => 0
                    ),

                array(
                        "Dated" => "2017-04-06",
                        "Nadeem" => 0,
                        "NadeemKaat" => 0,
                        "Ali" => 4800,
                        "AliKaat" => 96,
                        "Usman" => 0,
                        "UsmanKaat" => 0
                    ),

                array(
                        "Dated" => "2017-04-20",
                        "Nadeem" => 0,
                        "NadeemKaat" => 0,
                        "Ali" => 0,
                        "AliKaat" => 0,
                        "Usman" => 2100,
                        "UsmanKaat" => 42
                    )
            );
?>
<table align="center" border="1">
<tr>
    <th>Date</th>
    <th>Nadeem</th>
    <th>Ali</th>
    <th>Usman</th>
</tr>
<?php
foreach ($stock as $value) {
    ?><tr>
        <th><?php echo $value["Dated"] ?></th>
        <th><?php echo $value["Nadeem"] ?></th>
        <th><?php echo $value["Ali"] ?></th>
        <th><?php echo $value["Usman"] ?></th>
    </tr><?php
}