试图在子查询中引用模糊列

时间:2017-01-08 03:35:10

标签: json postgresql subquery

我正在尝试构建一个键入children.id列的JSON对象:

SELECT
  format('{%s}',
    string_agg(
      format(
        '%s:%s',
        to_json(children.id),
        row_to_json(t)
      ), ','
    ), ''
  )::json as json_object
FROM (
  SELECT 
    children.id,
    children.first_name,
    children.last_name,
    parents.id,
    parents.first_name,
    parents.last_name
  FROM  
    children 
  LEFT OUTER JOIN 
    parents ON parents.id = children.parent_id 
  ORDER BY 
    LOWER(children.last_name), 
    LOWER(children.first_name)
) t

将返回

之类的结果
{
  "1": {
    "id": "1",
    "first_name": "Joe",
    ...
  }
}

但是我收到了错误:

ERROR:  missing FROM-clause entry for table "children"
LINE 6:         to_json(children.id),
                    ^

我不知道在哪里可以另外提及"孩子"。

我不想诉诸于id列的别名,例如children.id AS child_id因为它破坏了输出,即:

{
  "1": {
    "child_id": "1", <----- NO GOOD
    "first_name": "Joe",
    ...
  }
}

可以这样做吗?

2 个答案:

答案 0 :(得分:0)

别名children位于子查询中。您只能访问t。也许你打算:

SELECT format('{%s}',
              string_agg(format('%s:%s', to_json(t.id), row_to_json(t)
-------------------------------------------------^
                               ), ','
                        ), ''
             )::json as json_object
. . .

在子查询中,您应该具有唯一的名称:

SELECT children.id as child_id,
       children.first_name as child_first_name,
       children.last_name as child_last_name,
       parents.id as parent_id,
       parents.first_name as parent_first_name,
       parents.last_name as parent_last_name

我真的很惊讶Postgres没有像其他许多数据库一样产生编译错误,子查询中有重复的列名。

答案 1 :(得分:0)

子查询输出包含2列名为id的列。和2列 名为first_namelast_name。重命名parents表列和 然后,您可以将t.id用作to_json()参数。

SELECT
  format('{%s}',
    string_agg(
      format(
        '%s:%s',
        to_json(t.id),
        row_to_json(t)
      ), ','
    ), ''
  )::json as json_object
FROM (
  SELECT
    children.id,
    children.first_name,
    children.last_name,
    parents.id AS parent_id,
    parents.first_name AS parent_first_name,
    parents.last_name AS parent_last_name
  FROM
    children
  LEFT OUTER JOIN
    parents ON parents.id = children.parent_id
  ORDER BY
    LOWER(children.last_name),
    LOWER(children.first_name)
) t