### How not to do it

A common pitfall is to be tempted to work with the many`XYZStep`

types. What types are these? They are usually invisible to the developer as developers use jOOQ’s DSL API in a fluent fashion, just like the JDK Stream API. For example:
```
DSLContext ctx = ...;
Result<?> result =
ctx.select(T.A, T.B)
.from(T)
.where(T.C.eq(1))
.and(T.D.eq(2))
.fetch();
```

```
SelectFromStep<?> s1 = ctx.select(T.A, T.B);
SelectWhereStep<?> s2 = s1.from(T);
SelectConditionStep<?> s3 = s2.where(T.C.eq(1));
SelectConditionStep<?> s4 = s3.and(T.D.eq(2))
Result<?> result = s4.fetch();
```

`T.D = 2`

) conditionally, e.g:
```
DSLContext ctx = ...;
SelectConditionStep<?> c =
ctx.select(T.A, T.B)
.from(T)
.where(T.C.eq(1));
if (something)
c = c.and(T.D.eq(2));
Result<?> result = c.fetch();
```

### Composing queries from its parts

The problem with the above approach is that it is trying to use an imperative approach of adding things to a query step by step. This is how many developers tend to structure their code, but with SQL (and by consequence, jOOQ) that can turn out to be difficult to get right. A functional approach tends to work better. Notice that not only the entire DSL structure could be assigned to local variables, but also the individual`SELECT`

clause arguments. For example:
```
DSLContext ctx = ...;
List<SelectField<?>> select = Arrays.asList(T.A, T.B);
Table<?> from = T;
Condition where = T.C.eq(1).and(T.D.eq(2));
Result<?> result =
ctx.select(select)
.from(from)
.where(where)
.fetch();
```

*every*jOOQ query is a dynamic SQL query. Many queries just happen to look like static queries, due to jOOQ’s API design. Again, we wouldn’t be assigning

*every*

`SELECT`

clause argument to a local variable, only the truly dynamic ones. For example:
```
DSLContext ctx = ...;
Condition where = T.C.eq(1);
if (something)
where = where.and(T.D.eq(2));
Result<?> result =
ctx.select(T.A, T.B)
.from(T)
.where(where)
.fetch();
```

### Avoid breaking readability

A lot of people aren’t happy with this approach either, because it breaks a query’s readability by making its components non-local. The predicates in the query are declared up front, away from the query itself. This isn’t how many people like to reason about SQL. And you don’t have to! It is totally possible to embed the condition directly in the`WHERE`

clause like this:
```
DSLContext ctx = ...;
Result<?> result =
ctx.select(T.A, T.B)
.from(T)
// We always need this predicate
.where(T.C.eq(1))
// This is only added conditionally
.and(something
? T.D.eq(2)
: DSL.noCondition())
.fetch();
```

`DSL.noCondition`

, which is a pseudo predicate that does not generate any content. It is a placeholder where an `org.jooq.Condition`

type is required without actually materialising one.
There is also:
`DSL.trueCondition`

:`TRUE`

or`1 = 1`

in SQL, the identity for`AND`

operation reductions.`DSL.falseCondition`

:`FALSE`

or`1 = 0`

in SQL, the identity for`OR`

operation reductions

`trueCondition()`

or `falseCondition()`

to a query, the resulting SQL tends to be quite ugly, for example for people having to analyse performance in production. `noCondition()`

just never generates any content at all.
Note that`noCondition()`

doesnotact as an identity! If your`noCondition()`

is the only predicate left in a`WHERE`

clause, there will not be any`WHERE`

clause, regardless if you work with`AND`

predicates or`OR`

predicates.

### No-op expressions in jOOQ

When using dynamic SQL like this, and adding things conditionally to queries, such “no-op expressions” become mandatory. In the previous example, we’ve seen how to add a “no-op predicate” to a`WHERE`

clause (the same approach would obviously work with `HAVING`

and all other clauses that work with boolean expressions).
The three most important jOOQ query types are:
`org.jooq.Field`

: for column expressions`org.jooq.Condition`

: for boolean column expressions / predicates`org.jooq.Table`

: for table expressions

**org.jooq.Condition**We’ve already seen how to do this with

`org.jooq.Condition`

.
**org.jooq.Field**What about dynamic column expressions in the projection (the

`SELECT`

clause)? Assuming you want to project columns only in certain cases. In our example, the `T.B`

column is something we don’t always need. That’s easy! The same approach can be used (assuming `T.B`

is a string column):
```
DSLContext ctx = ...;
Result<Record2<String, String>> result =
ctx.select(T.A, something ? T.B : DSL.inline("").as(T.B))
.from(T)
.where(T.C.eq(1))
.and(T.D.eq(2))
.fetch();
```

```
DSLContext ctx = ...;
Result<Record2<String, String>> result =
// First union subquery has a conditionally projected column
ctx.select(T.A, something ? T.B : DSL.inline("").as(T.B))
.from(T)
.where(T.C.eq(1))
.and(T.D.eq(2))
.union(
// Second union subquery has no such conditions
select(U.A, U.B)
.from(U))
.fetch();
```

```
DSLContext ctx = ...;
Result<Record2<String, String>> result =
// First union subquery has a conditionally projected column
ctx.select(T.A, T.B)
.from(T)
.union(
something
? select(U.A, U.B).from(U)
: select(inline(""), inline("")).where(falseCondition())
)
.fetch();
```

**org.jooq.Table**Conditional table expressions usually appear when doing conditional joins. This is usually not done in isolation, but together with other conditional elements in a query. E.g. if some columns are projected conditionally, those columns may require an additional join, as they originate from another table than the tables that are used unconditionally. For example:

```
DSLContext ctx = ...;
Result<?> result =
ctx.select(
T.A,
T.B,
something ? U.X : inline(""))
.from(
something
? T.join(U).on(T.Y.eq(U.Y))
: T)
.where(T.C.eq(1))
.and(T.D.eq(2))
.fetch();
```

`JOIN`

expression, because `JOIN`

and `ON`

need to be provided independently. For simple cases as shown above, this is perfectly fine. In more complex cases, some auxiliary methods may be needed, or views.
### Conclusion

There are two important messages here in this post:- The XYZStep types are
**auxiliary types only**. They are there to make your dynamically constructed SQL statement*look like*static SQL. But you should never feel the need to assign them to local variables, or return them from methods. While it is not wrong to do so, there is almost always a better way to write dynamic SQL. - In jOOQ,
**every query is a dynamic query**. This is the benefit of composing SQL queries using an expression tree like the one that is used in jOOQ’s internals. You may not see the expression tree because the jOOQ DSL API mimicks static SQL statement syntax. But behind the scenes, you’re effectively building this expression tree. Every part of the expression tree can be produced dynamically, from local variables, methods, or expressions, such as conditional expressions. I’m looking forward to using the new JEP 361 switch expressions in dynamic SQL. Just like a SQL`CASE`

expression, some SQL statement parts can be constructed dynamically in the client, prior to passing them to the server.