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.
Related
I want to create a list joining with unique terms and different terms so that I can use this value in Table form base on terms. Below is the response i am getting
{
"message": "Number of records fetched is 1",
"data": [
{
"roll no": "3",
"studentName": "Anil Kapoor",
"detail": [
{
"marksObtained": 0,
"title": "Annual Exams English ( 100 )",
"term": "Annual Exams",
"subjectName": "English",
"maxMarks": 100,
"minMarks": 33,
"grade": "D",
},
{
"marksObtained": 22,
"title": "Annual Exams Hindi ( 100 )",
"term": "Annual Exams",
"subjectName": "Hindi",
"maxMarks": 100,
"minMarks": 33,
"grade": "D",
},
{
"marksObtained": 55,
"title": "Annual Exams Marathi ( 100 )",
"term": "Annual Exams",
"subjectName": "Marathi",
"maxMarks": 100,
"minMarks": 33,
"grade": "C+",
},
{
"marksObtained": 89,
"title": "Open Book Test 1 Hindi ( 150 )",
"term": "Open Book Test 1",
"subjectName": "Hindi",
"maxMarks": 150,
"minMarks": 100,
"grade": "A",
},
{
"marksObtained": 90,
"title": "Annual Exams Gujarati ( 100 )",
"term": "Annual Exams",
"subjectName": "Gujarati",
"maxMarks": 100,
"minMarks": 33,
"grade": "A+",
},
{
"marksObtained": 95,
"title": "Open Book Test 1 English ( 100 )",
"term": "Open Book Test 1",
"subjectName": "English",
"maxMarks": 100,
"minMarks": 50,
"grade": "A+",
},
{
"marksObtained": 98,
"title": "Open Book Test 1 Gujarati ( 400 )",
"term": "Open Book Test 1",
"subjectName": "Gujarati",
"maxMarks": 400,
"minMarks": 10,
"grade": "A+",
}
],
"totalMarks": 1050,
"totalObtained": 449,
"percentage": 42,
"grade": "C",
"session": "2022-2023"
}
],
"totalRecords": 0,
"smsCredit": null
}
I want to get a single list based on terms i.e annual exam,open book test etc.like
[[object list of annual terms],[object list of open book exams]] and so on
Use package collection , groupBy creates a dictionary from the array by grouping the key:
For more detail check this answer: link
Example: [note: Avoid force unwrapping, it is for testing]
const jsonStr =
'{"message":"Numberofrecordsfetchedis1","data":[{"rollno":"3","studentName":"AnilKapoor","detail":[{"marksObtained":0,"title":"AnnualExamsEnglish(100)","term":"AnnualExams","subjectName":"English","maxMarks":100,"minMarks":33,"grade":"D"},{"marksObtained":22,"title":"AnnualExamsHindi(100)","term":"AnnualExams","subjectName":"Hindi","maxMarks":100,"minMarks":33,"grade":"D"},{"marksObtained":55,"title":"AnnualExamsMarathi(100)","term":"AnnualExams","subjectName":"Marathi","maxMarks":100,"minMarks":33,"grade":"C+"},{"marksObtained":89,"title":"OpenBookTest1Hindi(150)","term":"OpenBookTest1","subjectName":"Hindi","maxMarks":150,"minMarks":100,"grade":"A"},{"marksObtained":90,"title":"AnnualExamsGujarati(100)","term":"AnnualExams","subjectName":"Gujarati","maxMarks":100,"minMarks":33,"grade":"A+"},{"marksObtained":95,"title":"OpenBookTest1English(100)","term":"OpenBookTest1","subjectName":"English","maxMarks":100,"minMarks":50,"grade":"A+"},{"marksObtained":98,"title":"OpenBookTest1Gujarati(400)","term":"OpenBookTest1","subjectName":"Gujarati","maxMarks":400,"minMarks":10,"grade":"A+"}],"totalMarks":1050,"totalObtained":449,"percentage":42,"grade":"C","session":"2022-2023"}],"totalRecords":0,"smsCredit":null}';
Employee emp = Employee.fromJson(json.decode(jsonStr));
var newList = groupBy(emp.data?.first.detail! as Iterable<Detail>,
(Detail detail) => detail.term);
var finalList = newList.values;
I have a PostgreSQL 12.x database. There is a column data in a table typename that contains jsonb values. The actual JSON data is not fixed to a particular structure; these are some examples:
{"emt": {"key": " ", "source": "INPUT"}, "id": 1, "fields": {}}
{"emt": {"key": "Stack Overflow", "source": "INPUT"}, "id": 2, "fields": {}}
{"emt": {"key": "https://www.domain.tld/index.html", "source": "INPUT"}, "description": {"key": "JSONB datatype", "source": "INPUT"}, "overlay": {"id": 5, "source": "bOv"}, "fields": {"id": 1, "description": "Themed", "recs ": "1"}}
What I'm trying to do is to get all the JSON keys bound to objects that:
Contain only two elements: key and source
source element must be bound to "INPUT"
Basically, for this example, the result should be: emt, description.
This is what I have so far, but it's not quite working as expected:
select distinct jsonb_object_keys(data) as keys
from typename
where jsonb_path_exists(data, '$.** ? (#.type() == "string" && # like_regex "INPUT")');
-- where jsonb_typeof(data -> ???) = 'object'
-- and jsonb_path_exists(data, '$.???.key ? (#.type() == "string")')
-- and jsonb_path_exists(data, '$.???.source ? (#.type() == "string" && # like_regex "INPUT")');
I write for you sample, maybe you will need:
with tbl as (
select '{"emt": {"key": " ", "source": "INPUT"}, "id": 1, "fields": {}}'::jsonb as jsondata
union all
select '{"emt": {"key": "Stack Overflow", "source": "INPUT"}, "id": 2, "fields": {}}'::jsonb
union all
select '{"emt": {"key": "https://www.domain.tld/index.html", "source": "INPUT"}, "description": {"key": "JSONB datatype", "source": "INPUT"}, "overlay": {"id": 5, "source": "bOv"}, "fields": {"id": 1, "description": "Themed", "recs ": "1"}}'::jsonb
)
select
jsondata->'emt' as emt,
jsondata->'description' as description
from
tbl
where
jsondata->'emt'->>'source' = 'INPUT'
Result:
|----------------------------------------------------------------+---------------------------------------------+
| emt | description |
|----------------------------------------------------------------+---------------------------------------------+
| {"key": " ", "source": "INPUT"} | |
| {"key": "Stack Overflow", "source": "INPUT"} | |
| {"key": "https://www.domain.tld/index.html", "source": "INPUT"}| {"key": "JSONB datatype", "source": "INPUT"}|
Some samples maybe need to you:
Sample1:
with tbl as (
select '{"emt": {"key": " ", "source": "INPUT"}, "id": 1, "fields": {}}'::jsonb as jsondata
union all
select '{"emt": {"key": "Stack Overflow", "source": "INPUT"}, "id": 2, "fields": {}}'::jsonb
union all
select '{"emt": {"key": "https://www.domain.tld/index.html", "source": "INPUT"}, "description": {"key": "JSONB datatype", "source": "INPUT"}, "overlay": {"id": 5, "source": "bOv"}, "fields": {"id": 1, "description": "Themed", "recs ": "1"}}'::jsonb
)
select distinct
jsonb_object_keys(jsondata->'emt') as keys
from
tbl
where
jsondata->'emt'->>'source' = 'INPUT'
Result:
| keys |
|-------|
| key |
| source|
Sample2:
with tbl as (
select '{"emt": {"key": " ", "source": "INPUT"}, "id": 1, "fields": {}}'::jsonb as jsondata
union all
select '{"emt": {"key": "Stack Overflow", "source": "INPUT"}, "id": 2, "fields": {}}'::jsonb
union all
select '{"emt": {"key": "https://www.domain.tld/index.html", "source": "INPUT"}, "description": {"key": "JSONB datatype", "source": "INPUT"}, "overlay": {"id": 5, "source": "bOv"}, "fields": {"id": 1, "description": "Themed", "recs ": "1"}}'::jsonb
)
select
count(distinct t1.keys) as emt_count,
count(distinct t1.descs) as desc_count
from (
select
jsonb_object_keys(jsondata->'emt') keys,
jsonb_object_keys(jsondata->'description') descs
from
tbl
where
jsondata->'emt'->>'source' = 'INPUT'
) t1
Result:
| emt_count | desc_count |
|-----------+------------|
| 2 | 2 |
Sample3:
with tbl as (
select '{"emt": {"key": " ", "source": "INPUT"}, "id": 1, "fields": {}}'::jsonb as jsondata
union all
select '{"emt": {"key": "Stack Overflow", "source": "INPUT"}, "id": 2, "fields": {}}'::jsonb
union all
select '{"emt": {"key": "https://www.domain.tld/index.html", "source": "INPUT"}, "description": {"key": "JSONB datatype", "source": "INPUT"}, "overlay": {"id": 5, "source": "bOv"}, "fields": {"id": 1, "description": "Themed", "recs ": "1"}}'::jsonb
)
select
jsondata->'emt'->>'key' as key,
jsondata->'emt'->>'source' as source,
jsondata->'description'->>'key' as desc_key,
jsondata->'description'->>'source' as desc_source
from
tbl
where
jsondata->'emt'->>'source' = 'INPUT'
Result:
| key | source | desc_key | desc_source |
|----------------------------------+--------+----------------+-------------+
| | input | | |
| Stack Overflow | INPUT | | |
| https://www.domain.tld/index.html| input | JSONB datatype | INPUT |
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)
STREAM-1:
[KSTREAM-SOURCE-0000000000]: null, {"id": 1, "name": "john", "age": 26, "updated_at": 1525774480752}
[KSTREAM-SOURCE-0000000000]: null, {"id": 2, "name": "jane", "age": 24, "updated_at": 1525774480784}
[KSTREAM-SOURCE-0000000000]: null, {"id": 3, "name": "julia", "age": 25, "updated_at": 1525774480827}
[KSTREAM-SOURCE-0000000000]: null, {"id": 4, "name": "jamie", "age": 22, "updated_at": 1525774480875}
[KSTREAM-SOURCE-0000000000]: null, {"id": 5, "name": "jenny", "age": 27, "updated_at": 1525774482927}
[KSTREAM-SOURCE-0000000000]: null, {"id": 6, "name": "kishore", "age": 27, "updated_at": 1525775063908}
[KSTREAM-SOURCE-0000000000]: null, {"id": 7, "name": "purna", "age": 27, "updated_at": 1525775072006}
[KSTREAM-SOURCE-0000000000]: null, {"id": 8, "name": "xxx", "age": 10, "updated_at": 1525783464123}
[KSTREAM-SOURCE-0000000000]: null, {"id": 9, "name": "yyy", "age": 10, "updated_at": 1525783667644}
[KSTREAM-SOURCE-0000000000]: null, {"id": 10, "name": "zzz", "age": 10, "updated_at": 1525783741814}
STREAM-2:
[KSTREAM-SOURCE-0000000002]: null, {"id": 1, "name": "d", "age": 67}
[KSTREAM-SOURCE-0000000002]: null, {"id": 2, "name": "e", "age": 78}
[KSTREAM-SOURCE-0000000002]: null, {"id": 12, "name": "d", "age": 67}
[KSTREAM-SOURCE-0000000002]: null, {"id": 21, "name": "e", "age": 78}
Now I want to perform JOIN operation on both the streams and want to retrieve rows of stream-1 only that are not present in stream-2. My input streams data was AVRO format
Expected Output :
[KSTREAM-SOURCE-0000000000]: null, {"id": 3, "name": "julia", "age": 25, "updated_at": 1525774480827}
[KSTREAM-SOURCE-0000000000]: null, {"id": 4, "name": "jamie", "age": 22, "updated_at": 1525774480875}
[KSTREAM-SOURCE-0000000000]: null, {"id": 5, "name": "jenny", "age": 27, "updated_at": 1525774482927}
[KSTREAM-SOURCE-0000000000]: null, {"id": 6, "name": "kishore", "age": 27, "updated_at": 1525775063908}
[KSTREAM-SOURCE-0000000000]: null, {"id": 7, "name": "purna", "age": 27, "updated_at": 1525775072006}
[KSTREAM-SOURCE-0000000000]: null, {"id": 8, "name": "xxx", "age": 10, "updated_at": 1525783464123}
[KSTREAM-SOURCE-0000000000]: null, {"id": 9, "name": "yyy", "age": 10, "updated_at": 1525783667644}
[KSTREAM-SOURCE-0000000000]: null, {"id": 10, "name": "zzz", "age": 10, "updated_at": 1525783741814}
So which JOIN operation should I perform and how to achieve my expected output ? Can anyone help me out to achieve this
If you look at the documentation here: kafka streams join semantics you could possibly use a Left Join and just return null in your value joiner when values from stream2 are set.
Some pseudo code:
stream1.leftJoin(stream2, valueJoiner);
valueJoiner = (s1, s2) -> {if (s2 != null) {
return false
} else {
return true;
}
};
disclaimer: I have not tested this.
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)