jOOQ Postgres PERCENTILE_CONT & 类型转换的 MEDIAN 问题
jOOQ Postgres PERCENTILE_CONT & MEDIAN Issue with Type Casting
数据类型的强制转换似乎在 median()
或 percentileCont()
中不起作用。数据类型强制转换与 max()
和 min()
等其他聚合函数配合得很好。作为结果生成的 Postgres 查询显示类型转换未应用于最终结果。以下是来自 jOOQ
和 Postgres 的片段以供参考。截至目前,我还不知道此问题的公开票证的解决方法或知识。
任何方向将不胜感激!
中位数
jOOQ 片段
selectFields.add(
median(
field(String.format("%s.%s", a.getDataSourceName(), a.getField()))
.coerce(Double.class)) // Seems to not successfully coerce data types
.as(
String.format(
"%s.%s.%s", a.getDataSourceName(), a.getField(), "median")));
SQL输出
select
tableA.columnA,
percentile_cont(0.5) within group (order by tableA.columnA) as "tableA.columnA.median"
from tableA
group by tableA.columnA
limit 100;
ERROR: function percentile_cont(numeric, text) does not exist
PERCENTILE_CONT
jOOQ 片段
selectFields.add(
percentileCont(a.getPercentileValue())
.withinGroupOrderBy(
field(String.format("%s.%s", a.getDataSourceName(), a.getField()))
.coerce(Double.class)) // Seems to not successfully coerce data types
.as(
String.format(
"%s.%s.%s", a.getDataSourceName(), a.getField(), "percentile_" + Math.round(a.getPercentileValue() * 100))));
SQL输出
select
tableA.columnA,
percentile_cont(0.0) within group (order by tableA.columnA) as "tableA.columnA.percentile_0"
from tableA.columnA
group by tableA.columnA
limit 100;
ERROR: function percentile_cont(numeric, text) does not exist
POSTGRES -- 这是由于类型转换而起作用的
select
percentile_cont(0.5)
within group (
order by tableA.columnA::INTEGER
)
as "tableA.columnA.median"
from tableA.columnA
group by (select 1)
https://www.jooq.org/javadoc/latest/org.jooq/module-summary.html
您不是在寻找强制转换,在 jOOQ 中,强制转换意味着仅 在客户端 中更改数据类型而不让服务器知道。这在获取某种类型的数据(例如 Integer
)时非常有用,尽管 jOOQ 会生成一些其他数据类型(例如 BigInteger
),否则。请参阅 Field.coerce()
上的 Javadoc
Unlike with casting, coercing doesn't affect the way the database sees a Field's type.
// This binds an int value to a JDBC PreparedStatement
DSL.val(1).coerce(String.class);
// This binds an int value to a JDBC PreparedStatement
// and casts it to VARCHAR in SQL
DSL.val(1).cast(String.class);
Cleary,您想要 Field.cast()
,就像在您实际使用演员表的示例中一样 tableA.columnA::INTEGER
。
数据类型的强制转换似乎在 median()
或 percentileCont()
中不起作用。数据类型强制转换与 max()
和 min()
等其他聚合函数配合得很好。作为结果生成的 Postgres 查询显示类型转换未应用于最终结果。以下是来自 jOOQ
和 Postgres 的片段以供参考。截至目前,我还不知道此问题的公开票证的解决方法或知识。
任何方向将不胜感激!
中位数
jOOQ 片段selectFields.add(
median(
field(String.format("%s.%s", a.getDataSourceName(), a.getField()))
.coerce(Double.class)) // Seems to not successfully coerce data types
.as(
String.format(
"%s.%s.%s", a.getDataSourceName(), a.getField(), "median")));
SQL输出
select
tableA.columnA,
percentile_cont(0.5) within group (order by tableA.columnA) as "tableA.columnA.median"
from tableA
group by tableA.columnA
limit 100;
ERROR: function percentile_cont(numeric, text) does not exist
PERCENTILE_CONT
jOOQ 片段selectFields.add(
percentileCont(a.getPercentileValue())
.withinGroupOrderBy(
field(String.format("%s.%s", a.getDataSourceName(), a.getField()))
.coerce(Double.class)) // Seems to not successfully coerce data types
.as(
String.format(
"%s.%s.%s", a.getDataSourceName(), a.getField(), "percentile_" + Math.round(a.getPercentileValue() * 100))));
SQL输出
select
tableA.columnA,
percentile_cont(0.0) within group (order by tableA.columnA) as "tableA.columnA.percentile_0"
from tableA.columnA
group by tableA.columnA
limit 100;
ERROR: function percentile_cont(numeric, text) does not exist
POSTGRES -- 这是由于类型转换而起作用的
select
percentile_cont(0.5)
within group (
order by tableA.columnA::INTEGER
)
as "tableA.columnA.median"
from tableA.columnA
group by (select 1)
https://www.jooq.org/javadoc/latest/org.jooq/module-summary.html
您不是在寻找强制转换,在 jOOQ 中,强制转换意味着仅 在客户端 中更改数据类型而不让服务器知道。这在获取某种类型的数据(例如 Integer
)时非常有用,尽管 jOOQ 会生成一些其他数据类型(例如 BigInteger
),否则。请参阅 Field.coerce()
Unlike with casting, coercing doesn't affect the way the database sees a Field's type.
// This binds an int value to a JDBC PreparedStatement DSL.val(1).coerce(String.class); // This binds an int value to a JDBC PreparedStatement // and casts it to VARCHAR in SQL DSL.val(1).cast(String.class);
Cleary,您想要 Field.cast()
,就像在您实际使用演员表的示例中一样 tableA.columnA::INTEGER
。