【问题标题】:How to "zip" multiple nested JSON arrays without using id key?如何在不使用 id 键的情况下“压缩”多个嵌套的 JSON 数组?
【发布时间】:2019-02-21 10:59:06
【问题描述】:

我正在尝试合并一些嵌套的 JSON 数组而不查看 id。目前,当我向/surveyresponses 发出GET 请求时,我得到了这个:

{
"surveys": [
    {
        "id": 1,
        "name": "survey 1",
        "isGuest": true,
        "house_id": 1
    },
    {
        "id": 2,
        "name": "survey 2",
        "isGuest": false,
        "house_id": 1
    },
    {
        "id": 3,
        "name": "survey 3",
        "isGuest": true,
        "house_id": 2
    }
],
"responses": [
    {
        "question": "what is this anyways?",
        "answer": "test 1"
    },
    {
        "question": "why?",
        "answer": "test 2"
    },
    {
        "question": "testy?",
        "answer": "test 3"
    }
]
}

但我想在每个调查都有自己的问题和答案的地方得到它,所以像这样:

{
"surveys": [
    {
        "id": 1,
        "name": "survey 1",
        "isGuest": true,
        "house_id": 1
        "question": "what is this anyways?",
        "answer": "test 1"
    }
]
}

因为我不会去特定的id,所以我不确定如何让这种关系发挥作用。这是产生这些结果的当前查询。

export function getSurveyResponse(id: number): QueryBuilder {
return db('surveys')
    .join('questions', 'questions.survey_id', '=', 'surveys.id')
    .join('questionAnswers', 'questionAnswers.question_id', '=', 'questions.id')
    .select('surveys.name', 'questions.question', 'questions.question', 'questionAnswers.answer')
    .where({ survey_id: id, question_id: id })
}

【问题讨论】:

  • 请先声明您的 Postgres 版本和表定义。 jsonjsonb?
  • 我冒昧地修正了术语和语法以使问题保持​​一致。我做对了吗?

标签: sql node.js postgresql express


【解决方案1】:

假设 jsonb 在当前 Postgres 1011 中,这个查询可以完成这项工作:

SELECT t.data, to_jsonb(s) AS new_data
FROM   t
LEFT   JOIN LATERAL (
   SELECT jsonb_agg(s || r) AS surveys
   FROM  (
      SELECT jsonb_array_elements(t.data->'surveys') s
           , jsonb_array_elements(t.data->'responses') r
      ) sub
   ) s ON true;

db小提琴here

我将两个嵌套的 JSON 数组并行取消嵌套,以直接获得所需的“压缩”行为。两个嵌套 JSON 数组中的元素数量必须匹配,否则您需要做更多事情(否则会丢失数据)。

这建立在 Postgres 如何处理 SELECT 列表中的多个集合返回函数的实现细节之上,以使其简短而快速。见:

使用ROWS FROM 表达式可以更明确,自 Postgres 9.4 起该表达式可以正常工作:

SELECT t.data
     , to_jsonb(s) AS new_data
FROM   tbl t
LEFT   JOIN LATERAL (
   SELECT jsonb_agg(s || r) AS surveys
   FROM   ROWS FROM (jsonb_array_elements(t.data->'surveys') 
                   , jsonb_array_elements(t.data->'responses')) sub(s,r)
   ) s ON true;

The manual about combining multiple table functions.

或者您可以使用WITH ORDINALITY 获取元素的原始顺序并根据需要进行组合:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    • 2020-05-18
    • 2020-06-27
    • 2022-07-20
    • 1970-01-01
    相关资源
    最近更新 更多