I am storing the assessments of students in a jsonb column call assessment, every row in the database stores the assessments of students for a particular subject, and i am trying to get a query that will help retrieve:
1. A student assessment for a particular subject.
2. All the student assessments for every subject offer by the student.
Here is a same of the result i get when i select all records from the table.
[
{
"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"
}
]
}
]
This result contains assessment for the different subjects, with subjectIds, 8, 9 ,and 10 for two students with ids 2 and 3.
NOTE: sessionID,SectionID and subjectId are also columns in the table call assessment.
I should be able to get this object in return if i want a student with id 2 assessment for a subjectId of 9 and sessionId is 3 and also sectionId is 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"
}
And i should be a to get this result, if i want a student with id 2 assessment for all three subjectIds, i.e id 8, 9, 10, and sessionId is 3 and also sectionId is 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"
},
{
"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"
}
]
Minimized your data in the fiddle to:
[
{
"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
The first step is to unnest the relevant id information:
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
This results in:
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
The json_array_elements() function unnest the json array into one record per array element. Because there are two nested arrays, you need to call this function twice. You can get the values of each level as you can see within the SELECT list.
After that you are able to filter whatever you want within the WHERE clause. The resulting records (the relevant assessment objects) can be grouped with json_agg() aggregate function:
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)
or
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)
Related
How can I flatten "Behavior" field so it becomes part of the document root ? I have tried with $project and $unwind functions but that ones did not seem to help me
I have json data like this:
"breed": "Akita",
"origin": "Japan",
"url": "https://en.wikipedia.org/wiki/Akita_(dog)",
"img": "some img url",
"WikiDescr": [
{
"contenido": "Content"
}
],
"Behavior": [
{
"good_with_children": 3,
"good_with_other_dogs": 1,
"shedding": 3,
"grooming": 3,
"drooling": 1,
"coat_length": 1,
"good_with_strangers": 2,
"playfulness": 3,
"protectiveness": 5,
"trainability": 3,
"energy": 4,
"barking": 2,
"min_life_expectancy": 10,
"max_life_expectancy": 14,
"max_height_male": 28,
"max_height_female": 28,
"max_weight_male": 130,
"max_weight_female": 100,
"min_height_male": 26,
"min_height_female": 26,
"min_weight_male": 100,
"min_weight_female": 70
}
and my desired output would be like this:
"breed": "Akita",
"origin": "Japan",
"url": "https://en.wikipedia.org/wiki/Akita_(dog)",
"img": "some img url",
"good_with_children": 3,
"good_with_other_dogs": 1,
"shedding": 3,
"grooming": 3,
"drooling": 1,
"coat_length": 1,
"good_with_strangers": 2,
"playfulness": 3,
"protectiveness": 5,
"trainability": 3,
"energy": 4,
"barking": 2,
"min_life_expectancy": 10,
"max_life_expectancy": 14,
"max_height_male": 28,
"max_height_female": 28,
"max_weight_male": 130,
"max_weight_female": 100,
"min_height_male": 26,
"min_height_female": 26,
"min_weight_male": 100,
"min_weight_female": 70
},
"WikiDescr": [
{
"contenido": "content"
}
],
I have tried this but it does not happen anything:
{ $unwind: "$Behavior" },
{ $replaceRoot: { newRoot: { $mergeObjects: ["$Behavior", "$$ROOT"] } } },
Any help would be appreciated since I am stuck with this trivial question
My colleague is response for backend development, this is one of example of the API response.
I want to know that how can I separate it to the map?
And There have same name, I am very difficult to handle it. JSON to Dart generated code also will have error case by same name.
Is there have any other solution to handle this Json?
{
"formId": 1,
"formTypeId": 2,
"formTemplateId": 1,
"version": 1,
"history": "N",
"refNum": "AGQ/T01/01/A1/QA2/0001",
"dateOfAcceptance": "2020/12/16 14:54:01",
"dateOfReacceptance": "2020/12/16 14:54:01",
"blockId": 242,
"floorId": 1,
"flatId": 98,
"isPublic": "N",
"locationId": 1,
"fromFloorId": 1,
"toFloorId": 2,
"elevationId": 1,
"isNextVendor": "Y",
"isMultipleVendor": "N",
"formStatusId": 1,
"checkResults": 1,
"submissionDate": "2020/12/16 14:54:01",
"submittedBy": "ADMINISTRATOR",
"siteId": "YLTL",
"formDetails": [
{
"formDetailsId": 1,
"formId": 1,
"title": "A. 驗收項目",
"checkType": 1,
"required": "Y",
"parentId": 0,
"orderNum": 1,
"formDetailsOptions": [],
"fromDetails": [
{
"formDetailsId": 3,
"formId": 1,
"title": "Title group",
"checkType": 2,
"required": "Y",
"parentId": 1,
"orderNum": 1,
"formDetailsOptions": [],
"fromDetails": [
{
"formDetailsId": 4,
"formId": 1,
"title": "門編號:",
"checkType": 5,
"required": "Y",
"parentId": 3,
"orderNum": 1,
"answerVal": "A001",
"formDetailsOptions": []
},
{
"formDetailsId": 5,
"formId": 1,
"title": "位置:",
"checkType": 6,
"required": "Y",
"parentId": 3,
"orderNum": 2,
"formDetailsOptions": [
{
"formDetailsOptionsId": 1,
"formDetailsId": 5,
"orderNum": 1,
"optionDesc": "單位大門",
"defectOpts": "N",
"additionOpts": "N",
"selected": "N"
},
{
"formDetailsOptionsId": 2,
"formDetailsId": 5,
"orderNum": 2,
"optionDesc": "廚房門",
"defectOpts": "N",
"additionOpts": "N",
"selected": "N"
},
{
"formDetailsOptionsId": 3,
"formDetailsId": 5,
"orderNum": 3,
"optionDesc": "廁所客廳",
"defectOpts": "N",
"additionOpts": "N",
"selected": "N"
}
]
},
{
"formDetailsId": 6,
"formId": 1,
"title": "假框抆塞:",
"checkType": 4,
"required": "Y",
"parentId": 3,
"orderNum": 3,
"answerVal": "Y",
"formDetailsOptions": []
},
{
"formDetailsId": 7,
"formId": 1,
"title": "門框尺寸:",
"checkType": 4,
"required": "Y",
"parentId": 3,
"orderNum": 4,
"answerVal": "Y",
"formDetailsOptions": []
},
{
"formDetailsId": 8,
"formId": 1,
"title": "門框木料:",
"checkType": 4,
"required": "Y",
"parentId": 3,
"orderNum": 5,
"answerVal": "Y",
"formDetailsOptions": []
},
{
"formDetailsId": 9,
"formId": 1,
"title": "門框接口:",
"checkType": 4,
"required": "Y",
"parentId": 3,
"orderNum": 6,
"answerVal": "Y",
"formDetailsOptions": []
},
{
"formDetailsId": 10,
"formId": 1,
"title": "門框色澤:",
"checkType": 4,
"required": "Y",
"parentId": 3,
"orderNum": 7,
"answerVal": "Y",
"formDetailsOptions": []
},
{
"formDetailsId": 11,
"formId": 1,
"title": "磨耳及蟻油:",
"checkType": 4,
"required": "Y",
"parentId": 3,
"orderNum": 8,
"answerVal": "Y",
"formDetailsOptions": []
},
{
"formDetailsId": 12,
"formId": 1,
"title": "防火膠條:",
"checkType": 4,
"required": "Y",
"parentId": 3,
"orderNum": 9,
"answerVal": "Y",
"formDetailsOptions": []
},
{
"formDetailsId": 13,
"formId": 1,
"title": "平正及穩固:",
"checkType": 4,
"required": "Y",
"parentId": 3,
"orderNum": 10,
"answerVal": "Y",
"formDetailsOptions": []
},
{
"formDetailsId": 14,
"formId": 1,
"title": "備註:",
"checkType": 7,
"required": "N",
"parentId": 3,
"orderNum": 11,
"answerVal": "Test group remark",
"formDetailsOptions": []
}
]
}
]
},
{
"formDetailsId": 2,
"formId": 1,
"title": "B. 要改善位置及詳情備註:",
"checkType": 1,
"required": "Y",
"parentId": 0,
"orderNum": 2,
"answerVal": "Test B remark",
"formDetailsOptions": []
}
],
"formDefects": [
{
"formDefectsId": 1,
"formId": 1,
"defectRemark": "Test Remark",
"followActionId": 1,
"reporterType": 1,
"formDefectsImgs": [
{
"formDefectsImgId": 1,
"formDefectsId": 1,
"imgType": 1,
"filePath": "data/images/1/DEFECT-20201228150623123-2F3F4H.jpg",
"orderNum": 1
}
]
}
],
"formVendors": [
{
"formVendorId": 2,
"formId": 1,
"vendorId": "3954",
"orderNum": 2,
"isNextVendor": "N",
"formVendorImgs": [
{
"formVendorImgId": 1,
"formVendorId": 2,
"filePath": "data/images/1/QUERY-20201228151423123-2FF2V4.png",
"orderNum": 1
}
],
"vendor": {
"vendorId": "3954",
"vendorDesc": "博西華",
"vendorDescDisp": "BSH"
}
}
],
"formNextVendors": [
{
"formVendorId": 1,
"formId": 1,
"vendorId": "3985",
"orderNum": 1,
"isNextVendor": "Y",
"formVendorImgs": [
{
"formVendorImgId": 2,
"formVendorId": 1,
"filePath": "data/images/1/QUERY-20201228151423123-VD5F5H.png",
"orderNum": 2
}
],
"vendor": {
"vendorId": "3985",
"vendorDesc": "瑞基",
"vendorDescDisp": "Zuki"
}
}
]
}
With this kind of complex json i would suggest using dart packages for serialization. For example:
https://pub.dev/packages/json_serializable
or
https://pub.dev/packages/built_value
If you can share Dart models, then use json_serializable package. That would make things easier. But...
...if you have to live with the JSON response that your colleague developed and you cannot share your models that convert from/to Json, one alternative would be to use https://app.quicktype.io/
I entered your JSON response and out came generated Dart code that seems legit, at a first glance at least.
Example from that code generation:
factory ComplexJson.fromJson(Map<String, dynamic> json) => ComplexJson(
formId: json["formId"],
formTypeId: json["formTypeId"],
formTemplateId: json["formTemplateId"],
version: json["version"],
history: historyValues.map[json["history"]],
refNum: json["refNum"],
dateOfAcceptance: json["dateOfAcceptance"],
dateOfReacceptance: json["dateOfReacceptance"],
blockId: json["blockId"],
floorId: json["floorId"],
flatId: json["flatId"],
isPublic: historyValues.map[json["isPublic"]],
locationId: json["locationId"],
fromFloorId: json["fromFloorId"],
toFloorId: json["toFloorId"],
elevationId: json["elevationId"],
isNextVendor: historyValues.map[json["isNextVendor"]],
isMultipleVendor: historyValues.map[json["isMultipleVendor"]],
formStatusId: json["formStatusId"],
checkResults: json["checkResults"],
submissionDate: json["submissionDate"],
submittedBy: json["submittedBy"],
siteId: json["siteId"],
formDetails: List<MDetail>.from(json["formDetails"].map((x) => MDetail.fromJson(x))),
formDefects: List<FormDefect>.from(json["formDefects"].map((x) => FormDefect.fromJson(x))),
formVendors: List<FormVendor>.from(json["formVendors"].map((x) => FormVendor.fromJson(x))),
formNextVendors: List<FormVendor>.from(json["formNextVendors"].map((x) => FormVendor.fromJson(x))),
);
I have this data:
[
{ "_id": 1, "B": 1, "C": 1 },
{ "_id": 2, "B": 1, "C": 1 },
{ "_id": 3, "B": 1, "C": 2 },
{ "_id": 5, "B": 2, "C": 1 },
{ "_id": 6, "B": 2, "C": 1 },
{ "_id": 7, "B": 2, "C": 3 },
{ "_id": 8, "B": 3, "C": 1 },
{ "_id": 9, "B": 3, "C": 1 },
{ "_id": 10, "B": 3, "C": 1 }
]
What I want to know:
I like to get all distinct "B"s for which no "C"s exist with the value 2 or 3.
For the given data the result should be only 3 because for the other "B"s rows exist with "C" values 2 or 3.
In SQL I would create a left outer join to get this.
The following query should do
db.getCollection('foo').distinct("B", {"C" : {$nin: [2, 3]}});
I found out this query returns the correct result:
db.mytest.distinct("B", {"B" : {$nin: db.mytest.distinct("B", {"C" : {$in: [2, 3]}})}});
This may be long shot but is there any way to limit JSONB data with query?
We are investigating the differences between MongoDB and PostgreSQL JSONB and this may be a critical factor.
I have used both MongoDB and PostgreSQL (using JSONB) and IMO, PostgreSQL wins 90% of the time.
This is because most data in real-life is inherently relational and PostgreSQL gives you the best of both worlds. It's a powerful relational database but also has the flexibility of JSONB when required (e.g. JSON can be perfect for unstructured data).
It's disadvantages are at humongous (cough) scale - MongoDB can win then e.g. when there are huge amounts of raw JSON data (or data which can be easily converted to JSON) with no/limited relations.
The power of PostgreSQL JSONB is best illustrated with an example: -
Lets create a table (t) as follows: -
create table t (
id serial primary key,
data jsonb);
... with some demo data ...
insert into t (id, data)
values (1, '[{"name": "A", "age": 20},
{"name": "B", "age": 21},
{"name": "C", "age": 22},
{"name": "D", "age": 23},
{"name": "E", "age": 24},
{"name": "F", "age": 25},
{"name": "G", "age": 26}]'),
(2, '[{"name": "H", "age": 27},
{"name": "I", "age": 28},
{"name": "J", "age": 29},
{"name": "K", "age": 30},
{"name": "L", "age": 31}]'),
(3, '[{"name": "M", "age": 32},
{"name": "N", "age": 33},
{"name": "O", "age": 34},
{"name": "P", "age": 35},
{"name": "Q", "age": 36}]');
1. Simple select
If we simply select all from t we get 3 rows with a JSONB array in the data column.
select *
from t;
----+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
id | data
----+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 | [{"age": 20, "name": "A"}, {"age": 21, "name": "B"}, {"age": 22, "name": "C"}, {"age": 23, "name": "D"}, {"age": 24, "name": "E"}, {"age": 25, "name": "F"}, {"age": 26, "name": "G"}]
2 | [{"age": 27, "name": "H"}, {"age": 28, "name": "I"}, {"age": 29, "name": "J"}, {"age": 30, "name": "K"}, {"age": 31, "name": "L"}]
3 | [{"age": 32, "name": "M"}, {"age": 33, "name": "N"}, {"age": 34, "name": "O"}, {"age": 35, "name": "P"}, {"age": 36, "name": "Q"}]
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2. Select + Unnest
We can then "un-nest" the JSONB array in the data column by using the jsonb_array_elements function - this will return 17 rows of id and data JSONB objects.
select id,
jsonb_array_elements(data)
from t;
----+--------------------------
id | data
----+--------------------------
1 | {"age": 20, "name": "A"}
1 | {"age": 21, "name": "B"}
1 | {"age": 22, "name": "C"}
1 | {"age": 23, "name": "D"}
1 | {"age": 24, "name": "E"}
1 | {"age": 25, "name": "F"}
1 | {"age": 26, "name": "G"}
2 | {"age": 27, "name": "H"}
2 | {"age": 28, "name": "I"}
2 | {"age": 29, "name": "J"}
2 | {"age": 30, "name": "K"}
2 | {"age": 31, "name": "L"}
3 | {"age": 32, "name": "M"}
3 | {"age": 33, "name": "N"}
3 | {"age": 34, "name": "O"}
3 | {"age": 35, "name": "P"}
3 | {"age": 36, "name": "Q"}
-------------------------------
3. Select + Unnest + Pagination
We can then paginate the previous "un-nested" query above: -
select id,
jsonb_array_elements(data)
from t
limit 5; -- return 1st 5
----+---------------------------
id | data
----+---------------------------
1 | {"age": 20, "name": "A"}
1 | {"age": 21, "name": "B"}
1 | {"age": 22, "name": "C"}
1 | {"age": 23, "name": "D"}
1 | {"age": 24, "name": "E"}
--------------------------------
select id,
jsonb_array_elements(data)
from t
limit 5 offset 5; -- return next 5
----+---------------------------
id | data
----+---------------------------
1 | {"age": 25, "name": "F"}
1 | {"age": 26, "name": "G"}
2 | {"age": 27, "name": "H"}
2 | {"age": 28, "name": "I"}
2 | {"age": 29, "name": "J"}
--------------------------------
4. Select + Un-nest + Pagination + Re-nest
We can take this 1 step further and can group by id again and put the JSON back into an array using the jsonb_agg function: -
with t_unnested as (
select id,
jsonb_array_elements(data) as data
from t
limit 5 offset 5
)
select id, jsonb_agg (data)
from t_unnested
group by id;
----+--------------------------------------------------------------------------------
id | data
----+--------------------------------------------------------------------------------
1 | [{"age": 25, "name": "F"}, {"age": 26, "name": "G"}]
2 | [{"age": 27, "name": "H"}, {"age": 28, "name": "I"}, {"age": 29, "name": "J"}]
----+--------------------------------------------------------------------------------
5. Select + Un-nest + Pagination + Re-nest + Custom Object
We can take the previous query and re-construct a new object with new fields e.g. person_id and person_info. This
will return a single column with a new custom JSONB object (again a row per id).
with t_unnested as (
select id,
jsonb_array_elements(data) as data
from t
limit 5 offset 5
),
t_person as (
select jsonb_build_object (
'person_id', id,
'person_info', jsonb_agg (data)
) as person
from t_unnested
group by id
)
select person from t_person;
-----------------------------------------------------------------------------------------------------------------
person
-----------------------------------------------------------------------------------------------------------------
{"person_id": 1, "person_info": [{"age": 25, "name": "F"}, {"age": 26, "name": "G"}]}
{"person_id": 2, "person_info": [{"age": 27, "name": "H"}, {"age": 28, "name": "I"}, {"age": 29, "name": "J"}]}
-----------------------------------------------------------------------------------------------------------------
6. Select + Un-nest + Pagination + Re-nest + Custom Object + Further Re-Nest
The previous query returned 2 rows, we can create a single row by once again using the jsonb_agg function i.e.
with t_unnested as (
select id,
jsonb_array_elements(data) as data
from t
limit 5 offset 5
),
t_person as (
select jsonb_build_object (
'person_id', id,
'person_info', jsonb_agg (data)
) as person
from t_unnested
group by id
)
select jsonb_agg(person) from t_person;
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
person
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[{"person_id": 1, "person_info": [{"age": 25, "name": "F"}, {"age": 26, "name": "G"}]}, {"person_id": 2, "person_info": [{"age": 27, "name": "H"}, {"age": 28, "name": "I"}, {"age": 29, "name": "J"}]}]
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Hopefully this shows the power of JSONB / PostgreSQL in both storing JSONB, un-nesting (and re-nesting) JSON arrays with pagination.
A PostgreSQL 10 table contains JSON data like (here an SQL Fiddle):
[
{
"col": 7,
"row": 12,
"value": 3,
"letter": "A"
},
{
"col": 8,
"row": 12,
"value": 10,
"letter": "B"
},
{
"col": 9,
"row": 12,
"value": 1,
"letter": "C"
},
{
"col": 10,
"row": 12,
"value": 2,
"letter": "D"
}
]
How to extract only the "letter" values and concatenate them to a string like
ABCD
I suppose at the end I should use the ARRAY_TO_STRING function, but which JSON function to use for extracting the "letter" values to an array?
UPDATE:
Got a tip at the very helpful PostgreSQL mailing list too:
SELECT string_agg(x->>'letter','') FROM json_array_elements(
'[{"col": 7, "row": 12, "value": 3, "letter": "A"}, {"col": 8, "row": 12, "value": 10, "letter": "B"}, {"col": 9, "row": 12, "value": 1, "letter": "C"}, {"col": 10, "row": 12, "value": 2, "letter": "D"}]'::json
) x;
Use jsonb_array_elements() and string_agg():
with my_table(json_data) as (
values(
'[
{
"col": 7,
"row": 12,
"value": 3,
"letter": "A"
},
{
"col": 8,
"row": 12,
"value": 10,
"letter": "B"
},
{
"col": 9,
"row": 12,
"value": 1,
"letter": "C"
},
{
"col": 10,
"row": 12,
"value": 2,
"letter": "D"
}
]'::jsonb)
)
select string_agg(value->>'letter', '')
from my_table
cross join lateral jsonb_array_elements(json_data)
string_agg
------------
ABCD
(1 row)