I am unable to find documentation on how to dynamically construct WITH Clauses (i.e. Common Table Expressions / CTEs) in jOOQ. My use case is this :
- I need to nest dynamically created columns in order to produce new data from those dynamically created columns
- For example, I am creating a new field which is the non-null result from a full outer join. This field is ONLY available at the time of the query execution, so I need to store it within a WITH clause to reference it in other queries for additional calculations.
- Ideally, I would be able to request a WITH clause type query dynamically, and this dependency can be sorted out by placing this joined dataset in its own CTE to use in downstream references.
I am attempting to use the following, with no luck:
SelectQuery<Record> query =
getQuery(
dslContext,
selectFields,
fromClause,
groupFields,
conditionClause,
orderFields,
query.getOffset(),
query.getLimit());
// WORKS JUST FINE
Supplier<Stream<Map<String, Object>>> results = () ->
query
.fetchStream()
.map(Record::intoMap);
// make a nested query here. static for now.
// DOES NOT WORK
Supplier<Stream<Map<String, Object>>> resultsWith =
() ->
DSL.with("s1")
.as(query) // Shouldn't I be able to reference a SelectQuery here?
.select()
.from(table(name("s1")))
.fetchStream()
.map(Record::intoMap);
query.toString() looks something like this:
select
table1.field1,
coalesce(
table1.id,
table2.id) as table1.id_table2.id,
count(*) as table2.field1.count,
sum(table2.field2) as table2.field2.sum
from table1.table1 as table1
full outer join table2.table2 as table2
on table1.id = table2.id
where table1.field2 < 3000.0
group by
table1.id_table2.id,
table1.field1
order by table1.field1 asc
limit 100
What I would like to do at a minimum is to reference the coalesced
field above in additional downstream queries. Ideally I would not be limited at all in the manner or number of dynamic references I could make when constructing a WITH clause in jOOQ. In the end, I want to be able to dynamically create queries such as these, which show CTEs referencing CTEs too :
-- WITH Clause usage is preferrable
with
myFirstSelection as (
select
(id + 100) as newfield
from table1.table1 n
),
mySecondSelection as (
select
(newField + 200) as newerField
from myFirstSelection
)
select
*
from mySecondSelection
;
-- Inline queries, while not ideal, would be permissible
select
*
from (
select
(newField + 200) as newerField
from (
select
(id + 100) as newField
from table1.table1 n
) as myFirstSelection
) as mySecondSelection
;
Would that even be possible? Or am I limited to static tables and static selections?
LINKS
stackoverflow
- 'WITH' Clause not supported
- JOIN on a CTE in jOOQ
- Reference CTE in another CTE #1
Reference CTE in another CTE #2
jOOQ Website
GitHub
- Old CTETests repository which has been removed
- Issue 454 : Add CTE Support
- Issue 3174 : Add CTE Support w/ DML
- Issue 3175 : Nested CTE
- Issue 4474 : Form CTE from Plain SQL