[#3872] Emulate MEDIAN(x) via PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER

BY x) in PostgreSQL 9.4
This commit is contained in:
lukaseder 2014-12-20 12:31:25 +01:00
parent c04ce0e69e
commit 1abf3ec3ba
3 changed files with 26 additions and 10 deletions

View File

@ -10117,9 +10117,9 @@ public class DSL {
/**
* Get the median over a numeric field: median(field).
*/
@Support({ CUBRID, HSQLDB })
@Support({ CUBRID, HSQLDB, POSTGRES_9_4 })
public static AggregateFunction<BigDecimal> median(Field<? extends Number> field) {
return new Function<BigDecimal>("median", SQLDataType.NUMERIC, nullSafe(field));
return new Function<BigDecimal>(Term.MEDIAN, SQLDataType.NUMERIC, nullSafe(field));
}
/**
@ -10653,8 +10653,8 @@ public class DSL {
* function.
*/
@Support({ POSTGRES_9_4 })
public static OrderedAggregateFunction<Double> percentile_cont(double number) {
return new Function<Double>("percentile_cont", SQLDataType.DOUBLE, val(number));
public static OrderedAggregateFunction<BigDecimal> percentileCont(Number number) {
return percentileCont(val(number));
}
/**
@ -10663,8 +10663,8 @@ public class DSL {
* function.
*/
@Support({ POSTGRES_9_4 })
public static OrderedAggregateFunction<BigDecimal> percentile_cont(BigDecimal number) {
return new Function<BigDecimal>("percentile_cont", SQLDataType.NUMERIC, val(number, BigDecimal.class));
public static OrderedAggregateFunction<BigDecimal> percentileCont(Field<? extends Number> field) {
return new Function<BigDecimal>("percentile_cont", SQLDataType.NUMERIC, nullSafe(field));
}
/**
@ -10673,8 +10673,8 @@ public class DSL {
* function.
*/
@Support({ POSTGRES_9_4 })
public static OrderedAggregateFunction<Double> percentile_disc(Double number) {
return new Function<Double>("percentile_disc", SQLDataType.DOUBLE, val(number, Double.class));
public static OrderedAggregateFunction<BigDecimal> percentileDisc(Number number) {
return percentileDisc(val(number));
}
/**
@ -10683,8 +10683,8 @@ public class DSL {
* function.
*/
@Support({ POSTGRES_9_4 })
public static OrderedAggregateFunction<BigDecimal> percentile_disc(BigDecimal number) {
return new Function<BigDecimal>("percentile_disc", SQLDataType.NUMERIC, val(number, BigDecimal.class));
public static OrderedAggregateFunction<BigDecimal> percentileDisc(Field<? extends Number> field) {
return new Function<BigDecimal>("percentile_disc", SQLDataType.NUMERIC, nullSafe(field));
}
/**

View File

@ -54,11 +54,14 @@ import static org.jooq.SQLDialect.POSTGRES_9_4;
import static org.jooq.impl.DSL.condition;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.one;
import static org.jooq.impl.DSL.percentileCont;
import static org.jooq.impl.Term.LIST_AGG;
import static org.jooq.impl.Term.MEDIAN;
import static org.jooq.impl.Term.ROW_NUMBER;
import static org.jooq.impl.Utils.DATA_LOCALLY_SCOPED_DATA_MAP;
import static org.jooq.impl.Utils.DATA_WINDOW_DEFINITIONS;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
@ -202,6 +205,13 @@ class Function<T> extends AbstractField<T> implements
xxxxxxxxxxxxxxxxx
x
xx [/pro] */
else if (term == MEDIAN && asList(POSTGRES).contains(ctx.family())) {
Field<?>[] fields = new Field[arguments.size()];
for (int i = 0; i < fields.length; i++)
fields[i] = DSL.field("{0}", arguments.get(i));
ctx.visit(percentileCont(new BigDecimal("0.5")).withinGroupOrderBy(fields));
}
else {
toSQLArguments(ctx);
toSQLKeepDenseRankOrderByClause(ctx);

View File

@ -146,6 +146,12 @@ enum Term {
return "listagg";
}
},
MEDIAN {
@Override
public String translate(SQLDialect dialect) {
return "median";
}
},
OCTET_LENGTH {
@Override
public String translate(SQLDialect dialect) {