I have three tables: SchoolTable
, SchoolOrgTable
, and SchoolDetailsTable
. The relationships between these tables are as follows:
SchoolTable
toSchoolOrgTable
is a one-to-many relationship.SchoolOrgTable
toSchoolDetailsTable
is a many-to-one relationship.
I’m currently retrieving data from these tables using a JOOQ query like this:
SelectJoinStep<Record> result = dsl.select()
.from(SchoolTable)
.join(SchoolOrgTable)
.on(SchoolTable.A_ID.eq(SchoolOrgTable.ATest_ID))
.leftJoin(SchoolOrgTable)
.on(SchoolTable.A_ID.eq(SchoolOrgTable.B_Id))
.leftJoin(SchoolDetailsTable)
.on(SchoolDetailsTable.C_ID.eq(SchoolOrgTable.B_ID));
However, the result I’m getting is duplicating the schoolId
for each associated SchoolDetails
. Here’s an example of what I’m currently getting:
[
{
"schoolId": 1,
"schoolName": "JaySchool",
"isActive": true,
"SchoolDetails": [
{
"detailsID": 1,
"detailsName": "Test",
"details": "schoolIsGood"
}
]
},
{
"schoolId": 1,
"schoolName": "JaySchool",
"isActive": true,
"SchoolDetails": [
{
"detailsID": 2,
"detailsName": "Test1",
"details": "awesome"
}
]
},
{
"schoolId": 2,
"schoolName": "TermSchool",
"isActive": true,
"SchoolDetails": [
{
"detailsID": 3,
"detailsName": "Test",
"details": "Nice"
}
]
}
]
I want the result to be structured like this, with each schoolId associated with its SchoolDetails:
Note: I should be able to groupBy schoolName,detailsName
[
{
"schoolId": 1,
"schoolName": "JaySchool",
"isActive": true,
"SchoolDetails": [
{
"detailsID": 1,
"detailsName": "Test",
"details": "schoolIsGood"
},
{
"detailsID": 2,
"detailsName": "Test1",
"details": "awesome"
}
]
},
{
"schoolId": 2,
"schoolName": "TermSchool",
"isActive": true,
"SchoolDetails": [
{
"detailsID": 3,
"detailsName": "test3",
"details": "Nice"
}
]
}
]
2
Answers
The simplest way to get nested JSON documents is by using jOOQ’s SQL/JSON support, e.g.
JSON_ARRAYAGG
. For example:You can use multiple ways to solve your issue
It’s like native query
Docs: https://www.jooq.org/doc/latest/manual/sql-building/column-expressions/aggregate-functions/multiset-agg-function/
multisetAgg operates on the same principle as directly specifying JSONObject (from first option), but you don’t have to prescribe everything explicitly
In this situation, this option is unlikely to work, but I am obliged to mention it. When executing the code, there will most likely be an incorrect alias binding. Perhaps this has been fixed in new versions
Docs: https://www.jooq.org/doc/latest/manual/sql-building/column-expressions/multiset-value-constructor/
Just like multisetAgg, multiset operates on the same principle as directly specifying JSONObject (from first option), but you don’t have to prescribe everything explicitly
Briefly about multiset: a subquery is used inside the construction, which can refer to one or more values from an external query. In this case, the internal request refers to SCHOOL.ID for filtering values. This option is the most flexible