java - jooq 嵌套选择和类型安全
问题描述
我正在尝试在jooq中编写以下sql:
SELECT SUM(`sum`) AS `total`
FROM(
SELECT
MIN(`num_views`) AS `sum`
FROM `fact_wishlist`
GROUP BY `id`
) AS t
我发现了一些适用于此的东西:
Table<Record2<String, Integer>> nested =
table(create.select(MYTABLE.ID,
min(MYTABLE.NUM_VIEWS)
.as("views"))
.from(MYTABLE)
.groupBy(MYTABLE.ID));
return create.select(sum((Field<Integer>) nested.field("views")))
.from(nested)
.fetchOne().value1().longValue();
但是,不知何故,我失去了类型安全性。我觉得我在做一些明显的错误,但我没有看到它。关于如何改进的任何想法?
解决方案
不幸的是,您无法在 jOOQ 中使用派生表实现 100% 的类型安全,因为 Java 编译器无法真正证明派生表包含列。但是您的使用肯定可以通过重用该"views"
字段来改善。只需将其分配给局部变量即可。
Field<Integer> views = min(MYTABLE.NUM_VIEWS).as("views");
Table<Record2<String, Integer>> nested =
table(create.select(MYTABLE.ID, min(views))
.from(MYTABLE)
.groupBy(MYTABLE.ID));
return create.select(sum(nested.field(views)))
.from(nested)
.fetchOne().value1().longValue();
请注意该Table.field(Field<T>)
方法如何允许维护<T>
类型引用,假设您传入的字段确实存在于派生表中,按其给定名称,并且它与您的参数字段的类型匹配。
使用窗口函数的替代方法
请注意,您的查询可以使用窗口函数重写,如下所示。
SELECT SUM(MIN(num_views)) OVER ()
FROM fact_wishlist
GROUP BY id
LIMIT 1
或者在 jOOQ 中:
return
create.select(sum(min(MYTABLE.NUM_VIEWS)).over())
.from(MYTABLE)
.groupBy(MYTABLE.ID)
.limit(inline(1))
.fetchSingle()
.value1().longValue();
这当然取决于您的数据库是否支持窗口函数,并且它可能比您的双重聚合解决方案更快/更慢,这也取决于供应商。
推荐阅读
- javascript - 承诺解决问题
- c - uint vs. unsigned int - 为什么不用 typedef uint?
- node.js - Mongoose 模型方法 - 如果唯一则创建文档
- c++ - boost::multi_index_container MRU
- c# - 使用 xml 进行用户身份验证。C#
- angular - 如何避免通过 CLI 在 Lighthouse 中打开新选项卡?
- scala - 如何使用按月和 unix 纪元列给出的比率将 spark 数据帧拆分为 2?
- java - Forge MDK 1.15.2 在执行 runClient.launch 时崩溃
- angular - this.appRef.attachView 不是函数
- ssh - Cron Job 任务未在具有虚拟环境的服务器上执行 python 脚本