如何从Postgres jsonb列中选择特定对象

时间:2019-08-19 12:50:38

标签: postgresql jsonb

我将学生的评估存储在jsonb列调用评估中,数据库中的每一行都存储特定学科的学生评估,并且我试图获取一个查询来帮助检索: 1.对特定学科的学生评估。 2.学生对每门课程提供的所有学生评估。

这与我从表中选择所有记录时得到的结果相同。

[

     {
        "id": "22670f29-1437-4af1-b907-f6940377a851",
        "sessionId": 3,
        "sectionId": 4,
        "subjectId": 8,
        "assessment": [
            {
                "exam": 50,
                "grdae": "A",
                "total": 79,
                "position": "First",
                "student_id": 2,
                "assessment_1": 9,
                "assessment_2": 17,
                "assessment_4": 5,
                "student_name": "Anana Aristotle"
            },
            {
                "exam": 50,
                "grdae": "B",
                "total": 69,
                "position": "Third",
                "student_id": 3,
                "assessment_1": 9,
                "assessment_2": 17,
                "assessment_4": 5,
                "student_name": "Anana Elvis"
            }
        ]
    },
    {
        "id": "beca9d97-0d0a-4d89-b8c5-c9a6fed812a5",
        "sessionId": 3,
        "sectionId": 4,
        "subjectId": 10,
        "assessment": [
            {
                "exam": 50,
                "grdae": "A",
                "total": 79,
                "position": "First",
                "student_id": 2,
                "assessment_1": 9,
                "assessment_2": 17,
                "assessment_4": 5,
                "student_name": "Anana Aristotle"
            },
            {
                "exam": 50,
                "grdae": "B",
                "total": 69,
                "position": "Third",
                "student_id": 3,
                "assessment_1": 9,
                "assessment_2": 17,
                "assessment_4": 5,
                "student_name": "Anana Elvis"
            }
        ]
    },
    {
        "id": "1ed9c3d6-2482-4b1d-ab59-b77a8933699c",
        "sessionId": 3,
        "sectionId": 4,
        "subjectId": 9,
        "assessment": [
            {
                "exam": 50,
                "grdae": "A",
                "total": 90,
                "position": "First",
                "student_id": 2,
                "assessment_1": 9,
                "assessment_2": 17,
                "assessment_4": 5,
                "student_name": "Anana Aristotle"
            },
            {
                "exam": 50,
                "grdae": "B",
                "total": 69,
                "position": "Third",
                "student_id": 3,
                "assessment_1": 9,
                "assessment_2": 17,
                "assessment_4": 5,
                "student_name": "Anana Elvis"
            }
        ]
    }
]

此结果包含对不同学科的评估,两个id为2和3的学生的subjectId为8、9和10。

注意:sessionIDSectionIDsubjectId也是表调用评估中的列。

如果我想要一个id为2的学生,其subjectId为9,sessionId为3,sectionId为4,我应该可以得到这个对象:

         {
            "exam": 50,
            "grdae": "A",
            "total": 90,
            "position": "First",
            "student_id": 2,
            "assessment_1": 9,
            "assessment_2": 17,
            "assessment_4": 5,
            "student_name": "Anana Aristotle"
         }

如果我想让一个学生对所有三个subjectId(即id 8、9、10和sessionId为3,sectionId为4:id 2)进行评估,则我应该是a:

[
         {
            "exam": 50,
            "grdae": "A",
            "total": 90,
            "position": "First",
            "student_id": 2,
            "assessment_1": 9,
            "assessment_2": 17,
            "assessment_4": 5,
            "student_name": "Anana Aristotle"
         },
         {
            "exam": 50,
            "grdae": "A",
            "total": 79,
            "position": "First",
            "student_id": 2,
            "assessment_1": 9,
            "assessment_2": 17,
            "assessment_4": 5,
            "student_name": "Anana Aristotle"
        },
        {
            "exam": 50,
            "grdae": "A",
            "total": 79,
            "position": "First",
            "student_id": 2,
            "assessment_1": 9,
            "assessment_2": 17,
            "assessment_4": 5,
            "student_name": "Anana Aristotle"
        }
]

1 个答案:

答案 0 :(得分:1)

将您的数据最小化到:

[

     {
        "sessionId": 3,
        "sectionId": 4,
        "subjectId": 8,
        "assessment": [
            {              
                "student_id": 2
            },
            {
                "student_id": 3
            }
        ]
    },
    {
        "sessionId": 3,
        "sectionId": 4,
        "subjectId": 10,
        "assessment": [
            {
                "student_id": 2
            },
            {
                "student_id": 3
            }
        ]
    },
    {
        "sessionId": 3,
        "sectionId": 4,
        "subjectId": 9,
        "assessment": [
            {
                "student_id": 2
            },
            {
                "student_id": 3
            }
        ]
    }
]

demo:db<>fiddle

第一步是取消相关ID信息的嵌套:

SELECT
    assessments,
    (elems ->> 'sessionId')::int as session_id,
    (elems ->> 'sectionId')::int as section_id,
    (elems ->> 'subjectId')::int as subject_id,
    (assessments ->> 'student_id')::int AS student_id
FROM
    mytable,
    json_array_elements(jsondata) as elems,
    json_array_elements(elems -> 'assessment') as assessments

结果是:

assessments      | session_id | section_id | subject_id | student_id
:--------------- | ---------: | ---------: | ---------: | ---------:
{"student_id":2} |          3 |          4 |          8 |          2
{"student_id":3} |          3 |          4 |          8 |          3
{"student_id":2} |          3 |          4 |         10 |          2
{"student_id":3} |          3 |          4 |         10 |          3
{"student_id":2} |          3 |          4 |          9 |          2
{"student_id":3} |          3 |          4 |          9 |          3

json_array_elements()函数将json数组嵌套到每个数组元素一个记录中。因为有两个嵌套数组,所以您需要调用此函数两次。您可以在SELECT列表中看到每个级别的值。

之后,您可以在WHERE子句中过滤所需的任何内容。可以使用json_agg()聚合函数将结果记录(相关的评估对象)分组:

SELECT 
    json_agg(assessments)
FROM (
    -- query from above
) s
WHERE session_id IN (3)
    AND section_id IN (4)
    AND subject_id IN (9) -- only one subject
    AND student_id IN (2)

SELECT 
    json_agg(assessments)
FROM (
    -- query from above
) s
WHERE session_id IN (3)
    AND section_id IN (4)
    AND subject_id IN (8,9,10) -- more subjects
    AND student_id IN (2)