子查询
有类型子查询
基于单列的IN表达式
- Java
- Kotlin
BookTable book = Tables.BOOK_TABLE;
AuthorTableEx author = TableExes.AUTHOR_TABLE_EX;
List<Book> books = sqlClient
.createQuery(book)
.where(
book.id().in(sqlClient
.createSubQuery(author)
.where(author.firstName().eq("Alex"))
.select(author.books().id())
)
)
.select(book)
.execute();
val books = sqlClient
.createQuery(Book::class) {
where(
table.id valueIn subQuery(Author::class) {
where(table.firstName eq "Alex")
select(table.books.id)
}
)
select(table)
}
.execute()
最终生成的SQL如下
select
tb_1_.ID,
tb_1_.NAME,
tb_1_.EDITION,
tb_1_.PRICE,
tb_1_.STORE_ID
from BOOK as tb_1_
where
tb_1_.ID in (
select
tb_3_.BOOK_ID
from AUTHOR as tb_2_
inner join BOOK_AUTHOR_MAPPING as tb_3_
on tb_2_.ID = tb_3_.AUTHOR_ID
where
tb_2_.FIRST_NAME = ?
)
基于多列的IN表达式
- Java
- Kotlin
BookTable book = Tables.BOOK_TABLE;
List<Book> newestBooks = sqlClient
.createQuery(book)
.where(
Expression.tuple(
book.name(),
book.edition()
).in(sqlClient
.createSubQuery(book)
.groupBy(book.name())
.select(
book.name(),
book.edition().max()
)
)
)
.select(book)
.execute();
val newestBooks = sqlClient
.createQuery(Book::class) {
where(
tuple(
table.name,
table.edition
) valueIn subQuery(Book::class) {
groupBy(table.name)
select(
table.name,
max(table.edition).asNonNull()
)
}
)
select(table)
}
.execute()
最终生成的SQL如下
select
tb_1_.ID,
tb_1_.NAME,
tb_1_.EDITION,
tb_1_.PRICE,
tb_1_.STORE_ID
from BOOK as tb_1_
where
(tb_1_.NAME, tb_1_.EDITION) in (
select
tb_2_.NAME,
max(tb_2_.EDITION)
from BOOK as tb_2_
group by tb_2_.NAME
)
将子查询视为简单值
- Java
- Kotlin
BookTable book = Tables.BOOK_TABLE;
List<Book> newestBooks = sqlClient
.createQuery(book)
.where(
book.price().gt(sqlClient
.createSubQuery(book)
.groupBy(book.name())
.select(
book
.price()
.avg()
.coalesce(BigDecimal.ZERO)
)
)
)
.select(book)
.execute();
val books = sqlClient
.createQuery(Book::class) {
where(
table.price gt subQuery(Book::class) {
select(
avg(table.price)
.coalesce(BigDecimal.ZERO)
)
}
)
select(table)
}
.execute()
最终生成的SQL如下
select
tb_1_.ID,
tb_1_.NAME,
tb_1_.EDITION,
tb_1_.PRICE,
tb_1_.STORE_ID
from BOOK as tb_1_
where
tb_1_.PRICE > (
select
coalesce(avg(tb_2_.PRICE), ?)
from BOOK as tb_2_
)
在select和orderBy子句中使用子查询
- Java
- Kotlin
BookStoreTable store = Tables.BOOK_STORE_TABLE;
BookTable book = Tables.BOOK_TABLE;
MutableRootQuery<BookStoreTable> query =
sqlClient.createQuery(store);
TypedSubQuery<BigDecimal> subQuery =
sqlClient
.createSubQuery(book)
.where(book.store().eq(store))
.select(
book
.price()
.avg()
.coalesce(BigDecimal.ZERO)
);
List<Tuple2<BookStore, BigDecimal>> storeAvgPriceTuples =
query
.orderBy(
subQuery.desc()
)
.select(
store,
subQuery
)
.execute();
val storeAvgPriceTuples = sqlClient
.createQuery(BookStore::class) {
val avgPriceSubQuery = subQuery(Book::class) {
where(table.store eq parentTable)
select(avg(table.price))
}
orderBy(
avgPriceSubQuery.desc()
)
select(
table,
avgPriceSubQuery
)
}
.execute()
最终生成的SQL如下
select
tb_1_.ID,
tb_1_.NAME,
tb_1_.WEBSITE,
(
select coalesce(avg(tb_2_.PRICE), ?)
from BOOK as tb_2_
)
from BOOK_STORE as tb_1_
order by (
select coalesce(avg(tb_2_.PRICE), ?)
from BOOK as tb_2_
) desc
使用any运算符
- Java
- Kotlin
BookTable book = Tables.BOOK_TABLE;
AuthorTableEx author = TableExes.AUTHOR_TABLE_EX;
List<Book> books = sqlClient
.createQuery(book)
.where(
book.id().eq(sqlClient
.createSubQuery(author)
.where(
author.firstName().in(
Arrays.asList("Alex", "Bill")
)
)
.select(author.books().id())
.any()
)
)
.select(book)
.execute();
val books = sqlClient
.createQuery(Book::class) {
where(
table.id eq any(
subQuery(Author::class) {
where(
table.firstName valueIn listOf(
"Alex",
"Bill"
)
)
select(table.id)
}
)
)
select(table)
}
.execute()
最终生成的SQL如下
select
tb_1_.ID,
tb_1_.NAME,
tb_1_.EDITION,
tb_1_.PRICE,
tb_1_.STORE_ID
from BOOK as tb_1_
where tb_1_.ID =
any(
select
tb_3_.BOOK_ID
from AUTHOR as tb_2_
inner join BOOK_AUTHOR_MAPPING as tb_3_
on tb_2_.ID = tb_3_.AUTHOR_ID
where
tb_2_.FIRST_NAME in (?, ?)
)
使用all运算符
- Java
- Kotlin
BookTable book = Tables.BOOK_TABLE;
AuthorTableEx author = TableExes.AUTHOR_TABLE_EX;
List<Book> books = sqlClient
.createQuery(book)
.where(
book.id().ne(sqlClient
.createSubQuery(author)
.where(
author.firstName().in(
Arrays.asList("Alex", "Bill")
)
)
.select(author.books().id())
.all()
)
)
.select(book)
.execute();
val books = sqlClient
.createQuery(Book::class) {
where(
table.id ne all(
subQuery(Author::class) {
where(
table.firstName valueIn listOf(
"Alex",
"Bill"
)
)
select(table.id)
}
)
)
select(table)
}
.execute()
最终生成的SQL如下
select
tb_1_.ID,
tb_1_.NAME,
tb_1_.EDITION,
tb_1_.PRICE,
tb_1_.STORE_ID
from BOOK as tb_1_
where tb_1_.ID =
all(
select
tb_3_.BOOK_ID
from AUTHOR as tb_2_
inner join BOOK_AUTHOR_MAPPING as tb_3_
on tb_2_.ID = tb_3_.AUTHOR_ID
where
tb_2_.FIRST_NAME in (?, ?)
)