英文:
jOOQ Postgres PERCENTILE_CONT & MEDIAN Issue with Type Casting
问题
Coercion of data types does not seem to work within median() or percentileCont(). Data type coercion works just fine with other aggregate functions like max() and min(). The Postgres queries that are produced as a result show that type casting is not applied in the final result.
MEDIAN
jOOQ Snippet
selectFields.add(
median(
field(String.format("%s.%s", a.getDataSourceName(), a.getField()))
.coerce(Double.class)) // 似乎无法成功强制转换数据类型
.as(
String.format(
"%s.%s.%s", a.getDataSourceName(), a.getField(), "median")));
SQL Output
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 Snippet
selectFields.add(
percentileCont(a.getPercentileValue())
.withinGroupOrderBy(
field(String.format("%s.%s", a.getDataSourceName(), a.getField()))
.coerce(Double.class)) // 似乎无法成功强制转换数据类型
.as(
String.format(
"%s.%s.%s", a.getDataSourceName(), a.getField(), "percentile_" + Math.round(a.getPercentileValue() * 100))));
SQL Output
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 -- This works due to type casting
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
英文:
Coercion of data types does not seem to work within median() or percentileCont(). Data type coercion works just fine with other aggregate functions like max() and min(). The Postgres queries that are produced as a result show that type casting is not applied in the final result. Below are the snippets from jOOQ and Postgres for reference. As of now, I have no work-around or knowledge of an open ticket for this issue.
Any direction would be much appreciated!
MEDIAN
jOOQ Snippet
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 Output
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 Snippet
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 Output
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 -- This works due to type casting
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
答案1
得分: 1
你并不在寻求强制转换,这在 jOOQ 中指的是仅在客户端更改数据类型,而不让服务器知道。这在从 jOOQ 产生某种其他数据类型(例如 BigInteger)的情况下,仍然对某种类型(例如 Integer)的数据进行获取时非常有用。请参阅关于 Field.coerce() 的 Javadoc。
> 与强制转换不同,强制转换不会影响数据库查看字段类型的方式。
>
> java
> // 这将一个 int 值绑定到 JDBC PreparedStatement
> DSL.val(1).coerce(String.class);
>
> // 这将一个 int 值绑定到 JDBC PreparedStatement
> // 并在 SQL 中将其强制转换为 VARCHAR
> DSL.val(1).cast(String.class);
>
很明显,你想要使用 Field.cast(),就像你的示例中实际使用了一个 cast tableA.columnA::INTEGER 一样。
英文:
You're not looking for coercion, which in jOOQ-speak means changing a data type only in the client without letting the server know. This is mostly useful when fetching data of some type (e.g. Integer) despite jOOQ producing some other data type (e.g. BigInteger), otherwise. See the Javadoc on Field.coerce()
> Unlike with casting, coercing doesn't affect the way the database sees a Field's type.
>
> java
> // 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, you want to Field.cast(), instead, just like in your example where you actually used a cast tableA.columnA::INTEGER.
专注分享java语言的经验与见解,让所有开发者获益!

评论