英文:
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论