[英]JOOQ multiple select count in one connection with PostgreSQL
我有一个表SUBSCRIPTION
,我想在一个连接中运行多个用selectCount
编写的selectCount
与数据库的不同谓词。 为此,我创建了一个查询列表:
List<Query> countQueries = channels.stream().map(c ->
selectCount().from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.equal(c))
).collect(toList());
最后,我使用batch
启动了这个查询列表:
using(configuration).batch(countQueries).execute();
我希望在execute
的返回值中有上述查询的结果,但我得到一个填充了0
值的整数数组。
这是使用 JOOQ 运行多个selectCount
的正确方法吗? execute
方法返回的整数数组的意义是什么?
我在 JOOQ 博客中检查了这个链接,谈论“如何在单个查询中计算多个聚合函数”,但它只是关于 SQL 查询,没有 JOOQ 方言。
我希望在 execute 的返回值中包含上述查询的结果,但我得到了一个填充为 0 值的整数数组。
batch()
API 只能用于 DML 查询( INSERT
、 UPDATE
、 DELETE
),就像原生 JDBC 一样。 我的意思是,您可以批量运行查询,但不能以这种方式获取结果。
我在 JOOQ 博客中检查了这个链接,谈论“如何在单个查询中计算多个聚合函数”,但它只是关于 SQL 查询,没有 JOOQ 方言。
普通 SQL 查询几乎总是从字面上转换为 jOOQ,因此您也可以在您的案例中应用该文章中的技术。 事实上,你应该! 运行这么多查询绝对不是一个好主意。
因此,让我们看看如何将简单的 SQL 示例从链接转换为您的案例:
Record record =
ctx.select(
channels.stream()
.map(c -> count().filterWhere(CHANNEL.CODE.equal(c)).as(c))
.collect(toList())
)
.from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.in(channels)) // Not strictly necessary, but might speed up things
.fetch();
这将生成包含所有计数值的单个记录。
与往常一样,这是假设以下静态导入
import static org.jooq.impl.DSL.*;
GROUP BY
当然,您也可以在特定情况下使用经典的GROUP BY
。 这甚至可能更快一点:
Result<?> result =
ctx.select(CHANNEL.CODE, count())
.from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.in(channels)) // This time, you need to filter
.groupBy(CHANNEL.CODE)
.fetchOne();
现在生成一个表,每个代码有一个计数值。 或者,将其提取到Map<String, Integer>
:
Map<String, Integer> map =
ctx.select(CHANNEL.CODE, count())
.from(SUBSCRIPTION)
.innerJoin(SENDER).on(SENDER.ID.equal(SUBSCRIPTION.SENDER_ID))
.innerJoin(CHANNEL).on(CHANNEL.ID.equal(SUBSCRIPTION.CHANNEL_ID))
.where(SENDER.CODE.equal(senderCode))
.and(CHANNEL.CODE.in(channels))
.groupBy(CHANNEL.CODE)
.fetchMap(CHANNEL.CODE, count());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.