/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.querydsl.sql;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.*;
import com.querydsl.core.types.dsl.*;
/**
* Common SQL expressions
*
* @author tiwe
*
*/
@SuppressWarnings("rawtypes")
public final class SQLExpressions {
private static final Map<DatePart, Operator> DATE_ADD_OPS
= new EnumMap<DatePart, Operator>(DatePart.class);
private static final Map<DatePart, Operator> DATE_DIFF_OPS
= new EnumMap<DatePart, Operator>(DatePart.class);
private static final Map<DatePart, Operator> DATE_TRUNC_OPS
= new EnumMap<DatePart, Operator>(DatePart.class);
static {
DATE_ADD_OPS.put(DatePart.year, Ops.DateTimeOps.ADD_YEARS);
DATE_ADD_OPS.put(DatePart.month, Ops.DateTimeOps.ADD_MONTHS);
DATE_ADD_OPS.put(DatePart.week, Ops.DateTimeOps.ADD_WEEKS);
DATE_ADD_OPS.put(DatePart.day, Ops.DateTimeOps.ADD_DAYS);
DATE_ADD_OPS.put(DatePart.hour, Ops.DateTimeOps.ADD_HOURS);
DATE_ADD_OPS.put(DatePart.minute, Ops.DateTimeOps.ADD_MINUTES);
DATE_ADD_OPS.put(DatePart.second, Ops.DateTimeOps.ADD_SECONDS);
DATE_ADD_OPS.put(DatePart.millisecond, null); // TODO
DATE_DIFF_OPS.put(DatePart.year, Ops.DateTimeOps.DIFF_YEARS);
DATE_DIFF_OPS.put(DatePart.month, Ops.DateTimeOps.DIFF_MONTHS);
DATE_DIFF_OPS.put(DatePart.week, Ops.DateTimeOps.DIFF_WEEKS);
DATE_DIFF_OPS.put(DatePart.day, Ops.DateTimeOps.DIFF_DAYS);
DATE_DIFF_OPS.put(DatePart.hour, Ops.DateTimeOps.DIFF_HOURS);
DATE_DIFF_OPS.put(DatePart.minute, Ops.DateTimeOps.DIFF_MINUTES);
DATE_DIFF_OPS.put(DatePart.second, Ops.DateTimeOps.DIFF_SECONDS);
DATE_DIFF_OPS.put(DatePart.millisecond, null); // TODO
DATE_TRUNC_OPS.put(DatePart.year, Ops.DateTimeOps.TRUNC_YEAR);
DATE_TRUNC_OPS.put(DatePart.month, Ops.DateTimeOps.TRUNC_MONTH);
DATE_TRUNC_OPS.put(DatePart.week, Ops.DateTimeOps.TRUNC_WEEK);
DATE_TRUNC_OPS.put(DatePart.day, Ops.DateTimeOps.TRUNC_DAY);
DATE_TRUNC_OPS.put(DatePart.hour, Ops.DateTimeOps.TRUNC_HOUR);
DATE_TRUNC_OPS.put(DatePart.minute, Ops.DateTimeOps.TRUNC_MINUTE);
DATE_TRUNC_OPS.put(DatePart.second, Ops.DateTimeOps.TRUNC_SECOND);
}
private static final WindowOver<Double> cumeDist = new WindowOver<Double>(Double.class, SQLOps.CUMEDIST);
private static final WindowOver<Long> rank = new WindowOver<Long>(Long.class, SQLOps.RANK);
private static final WindowOver<Long> denseRank = new WindowOver<Long>(Long.class, SQLOps.DENSERANK);
private static final WindowOver<Double> percentRank = new WindowOver<Double>(Double.class, SQLOps.PERCENTRANK);
private static final WindowOver<Long> rowNumber = new WindowOver<Long>(Long.class, SQLOps.ROWNUMBER);
private static Expression[] convertToExpressions(Object... args) {
Expression<?>[] exprs = new Expression<?>[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof Expression) {
exprs[i] = (Expression) args[i];
} else {
exprs[i] = ConstantImpl.create(args[i]);
}
}
return exprs;
}
/**
* Wildcard expression
*/
public static final Expression<Object[]> all = Wildcard.all;
/**
* Wildcard count expression
*/
public static final Expression<Long> countAll = Wildcard.count;
/**
* Create an assignment expression
*
* @param target target expression
* @param value value to be set
* @param <T>
* @return target = value
*/
public static <T> Expression<T> set(Path<T> target, Expression<? extends T> value) {
if (value != null) {
return Expressions.operation(target.getType(), SQLOps.SET_PATH, target, value);
} else {
return Expressions.operation(target.getType(), SQLOps.SET_LITERAL,
target, Expressions.nullExpression());
}
}
/**
* Create an assignment expression
*
* @param target target expression
* @param value value to be set
* @param <T>
* @return target = value
*/
public static <T> Expression<T> set(Path<T> target, T value) {
if (value != null) {
return Expressions.operation(target.getType(), SQLOps.SET_LITERAL,
target, Expressions.constant(value));
} else {
return Expressions.operation(target.getType(), SQLOps.SET_LITERAL,
target, Expressions.nullExpression());
}
}
/**
* Create a new detached SQLQuery instance with the given projection
*
* @param expr projection
* @param <T>
* @return select(expr)
*/
public static <T> SQLQuery<T> select(Expression<T> expr) {
return new SQLQuery<Void>().select(expr);
}
/**
* Create a new detached SQLQuery instance with the given projection
*
* @param exprs projection
* @return select(exprs)
*/
public static SQLQuery<Tuple> select(Expression<?>... exprs) {
return new SQLQuery<Void>().select(exprs);
}
/**
* Create a new detached SQLQuery instance with the given projection
*
* @param expr distinct projection
* @param <T>
* @return select(distinct expr)
*/
public static <T> SQLQuery<T> selectDistinct(Expression<T> expr) {
return new SQLQuery<Void>().select(expr).distinct();
}
/**
* Create a new detached SQLQuery instance with the given projection
*
* @param exprs distinct projection
* @return select(distinct exprs)
*/
public static SQLQuery<Tuple> selectDistinct(Expression<?>... exprs) {
return new SQLQuery<Void>().select(exprs).distinct();
}
/**
* Create a new detached SQLQuery instance with zero as the projection
*
* @return select(0)
*/
public static SQLQuery<Integer> selectZero() {
return select(Expressions.ZERO);
}
/**
* Create a new detached SQLQuery instance with one as the projection
*
* @return select(1)
*/
public static SQLQuery<Integer> selectOne() {
return select(Expressions.ONE);
}
/**
* Create a new detached SQLQuery instance with the given projection
*
* @param expr query source and projection
* @param <T>
* @return select(expr).from(expr)
*/
public static <T> SQLQuery<T> selectFrom(RelationalPath<T> expr) {
return select(expr).from(expr);
}
/**
* Create a new UNION clause
*
* @param sq subqueries
* @param <T>
* @return union
*/
public static <T> Union<T> union(SubQueryExpression<T>... sq) {
return new SQLQuery<Void>().union(sq);
}
/**
* Create a new UNION clause
*
* @param sq subqueries
* @param <T>
* @return union
*/
public static <T> Union<T> union(List<SubQueryExpression<T>> sq) {
return new SQLQuery<Void>().union(sq);
}
/**
* Create a new UNION ALL clause
*
* @param sq subqueries
* @param <T>
* @return union
*/
public static <T> Union<T> unionAll(SubQueryExpression<T>... sq) {
return new SQLQuery<Void>().unionAll(sq);
}
/**
* Create a new UNION ALL clause
*
* @param sq subqueries
* @param <T>
* @return union
*/
public static <T> Union<T> unionAll(List<SubQueryExpression<T>> sq) {
return new SQLQuery<Void>().unionAll(sq);
}
/**
* Get an aggregate any expression for the given boolean expression
*/
public static BooleanExpression any(BooleanExpression expr) {
return Expressions.booleanOperation(Ops.AggOps.BOOLEAN_ANY, expr);
}
/**
* Get an aggregate all expression for the given boolean expression
*/
public static BooleanExpression all(BooleanExpression expr) {
return Expressions.booleanOperation(Ops.AggOps.BOOLEAN_ALL, expr);
}
/**
* Create a new RelationalFunctionCall for the given function and arguments
*
* @param type type
* @param function function name
* @param args arguments
* @param <T>
* @return relational function call
*/
public static <T> RelationalFunctionCall<T> relationalFunctionCall(Class<? extends T> type, String function, Object... args) {
return new RelationalFunctionCall<T>(type, function, args);
}
/**
* Create a nextval(sequence) expression
*
* <p>Returns the next value from the give sequence</p>
*
* @param sequence sequence name
* @return nextval(sequence)
*/
public static SimpleExpression<Long> nextval(String sequence) {
return nextval(Long.class, sequence);
}
/**
* Create a nextval(sequence) expression of the given type
*
* <p>Returns the next value from the given sequence</p>
*
* @param type type of call
* @param sequence sequence name
* @return nextval(sequence)
*/
public static <T extends Number> SimpleExpression<T> nextval(Class<T> type, String sequence) {
return Expressions.operation(type, SQLOps.NEXTVAL, ConstantImpl.create(sequence));
}
/**
* Convert timestamp to date
*
* @param dateTime timestamp
* @return date
*/
public static <D extends Comparable> DateExpression<D> date(DateTimeExpression<D> dateTime) {
return Expressions.dateOperation(dateTime.getType(), Ops.DateTimeOps.DATE, dateTime);
}
/**
* Convert timestamp to date
*
* @param type type
* @param dateTime timestamp
* @return date
*/
public static <D extends Comparable> DateExpression<D> date(Class<D> type, DateTimeExpression<?> dateTime) {
return Expressions.dateOperation(type, Ops.DateTimeOps.DATE, dateTime);
}
/**
* Create a dateadd(unit, date, amount) expression
*
* @param unit date part
* @param date date
* @param amount amount
* @return converted date
*/
public static <D extends Comparable> DateTimeExpression<D> dateadd(DatePart unit, DateTimeExpression<D> date, int amount) {
return Expressions.dateTimeOperation(date.getType(), DATE_ADD_OPS.get(unit), date, ConstantImpl.create(amount));
}
/**
* Create a dateadd(unit, date, amount) expression
*
* @param unit date part
* @param date date
* @param amount amount
* @return converted date
*/
public static <D extends Comparable> DateExpression<D> dateadd(DatePart unit, DateExpression<D> date, int amount) {
return Expressions.dateOperation(date.getType(), DATE_ADD_OPS.get(unit), date, ConstantImpl.create(amount));
}
/**
* Get a datediff(unit, start, end) expression
*
* @param unit date part
* @param start start
* @param end end
* @return difference in units
*/
public static <D extends Comparable> NumberExpression<Integer> datediff(DatePart unit,
DateExpression<D> start, DateExpression<D> end) {
return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), start, end);
}
/**
* Get a datediff(unit, start, end) expression
*
* @param unit date part
* @param start start
* @param end end
* @return difference in units
*/
public static <D extends Comparable> NumberExpression<Integer> datediff(DatePart unit,
D start, DateExpression<D> end) {
return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), ConstantImpl.create(start), end);
}
/**
* Get a datediff(unit, start, end) expression
*
* @param unit date part
* @param start start
* @param end end
* @return difference in units
*/
public static <D extends Comparable> NumberExpression<Integer> datediff(DatePart unit,
DateExpression<D> start, D end) {
return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), start, ConstantImpl.create(end));
}
/**
* Get a datediff(unit, start, end) expression
*
* @param unit date part
* @param start start
* @param end end
* @return difference in units
*/
public static <D extends Comparable> NumberExpression<Integer> datediff(DatePart unit,
DateTimeExpression<D> start, DateTimeExpression<D> end) {
return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), start, end);
}
/**
* Get a datediff(unit, start, end) expression
*
* @param unit date part
* @param start start
* @param end end
* @return difference in units
*/
public static <D extends Comparable> NumberExpression<Integer> datediff(DatePart unit,
D start, DateTimeExpression<D> end) {
return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), ConstantImpl.create(start), end);
}
/**
* Get a datediff(unit, start, end) expression
*
* @param unit date part
* @param start start
* @param end end
* @return difference in units
*/
public static <D extends Comparable> NumberExpression<Integer> datediff(DatePart unit,
DateTimeExpression<D> start, D end) {
return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), start, ConstantImpl.create(end));
}
/**
* Truncate the given date expression
*
* @param unit date part to truncate to
* @param expr truncated date
*/
public static <D extends Comparable> DateExpression<D> datetrunc(DatePart unit, DateExpression<D> expr) {
return Expressions.dateOperation(expr.getType(), DATE_TRUNC_OPS.get(unit), expr);
}
/**
* Truncate the given datetime expression
*
* @param unit datepart to truncate to
* @param expr truncated datetime
*/
public static <D extends Comparable> DateTimeExpression<D> datetrunc(DatePart unit, DateTimeExpression<D> expr) {
return Expressions.dateTimeOperation(expr.getType(), DATE_TRUNC_OPS.get(unit), expr);
}
/**
* Add the given amount of years to the date
*
* @param date datetime
* @param years years to add
* @return converted datetime
*/
public static <D extends Comparable> DateTimeExpression<D> addYears(DateTimeExpression<D> date, int years) {
return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_YEARS, date, ConstantImpl.create(years));
}
/**
* Add the given amount of months to the date
*
* @param date datetime
* @param months months to add
* @return converted datetime
*/
public static <D extends Comparable> DateTimeExpression<D> addMonths(DateTimeExpression<D> date, int months) {
return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_MONTHS, date, ConstantImpl.create(months));
}
/**
* Add the given amount of weeks to the date
*
* @param date datetime
* @param weeks weeks to add
* @return converted date
*/
public static <D extends Comparable> DateTimeExpression<D> addWeeks(DateTimeExpression<D> date, int weeks) {
return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_WEEKS, date, ConstantImpl.create(weeks));
}
/**
* Add the given amount of days to the date
*
* @param date datetime
* @param days days to add
* @return converted datetime
*/
public static <D extends Comparable> DateTimeExpression<D> addDays(DateTimeExpression<D> date, int days) {
return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_DAYS, date, ConstantImpl.create(days));
}
/**
* Add the given amount of hours to the date
*
* @param date datetime
* @param hours hours to add
* @return converted datetime
*/
public static <D extends Comparable> DateTimeExpression<D> addHours(DateTimeExpression<D> date, int hours) {
return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_HOURS, date, ConstantImpl.create(hours));
}
/**
* Add the given amount of minutes to the date
*
* @param date datetime
* @param minutes minutes to add
* @return converted datetime
*/
public static <D extends Comparable> DateTimeExpression<D> addMinutes(DateTimeExpression<D> date, int minutes) {
return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_MINUTES, date, ConstantImpl.create(minutes));
}
/**
* Add the given amount of seconds to the date
*
* @param date datetime
* @param seconds seconds to add
* @return converted datetime
*/
public static <D extends Comparable> DateTimeExpression<D> addSeconds(DateTimeExpression<D> date, int seconds) {
return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_SECONDS, date, ConstantImpl.create(seconds));
}
/**
* Add the given amount of years to the date
*
* @param date date
* @param years years to add
* @return converted date
*/
public static <D extends Comparable> DateExpression<D> addYears(DateExpression<D> date, int years) {
return Expressions.dateOperation(date.getType(), Ops.DateTimeOps.ADD_YEARS, date, ConstantImpl.create(years));
}
/**
* Add the given amount of months to the date
*
* @param date date
* @param months months to add
* @return converted date
*/
public static <D extends Comparable> DateExpression<D> addMonths(DateExpression<D> date, int months) {
return Expressions.dateOperation(date.getType(), Ops.DateTimeOps.ADD_MONTHS, date, ConstantImpl.create(months));
}
/**
* Add the given amount of weeks to the date
*
* @param date date
* @param weeks weeks to add
* @return converted date
*/
public static <D extends Comparable> DateExpression<D> addWeeks(DateExpression<D> date, int weeks) {
return Expressions.dateOperation(date.getType(), Ops.DateTimeOps.ADD_WEEKS, date, ConstantImpl.create(weeks));
}
/**
* Add the given amount of days to the date
*
* @param date date
* @param days days to add
* @return converted date
*/
public static <D extends Comparable> DateExpression<D> addDays(DateExpression<D> date, int days) {
return Expressions.dateOperation(date.getType(), Ops.DateTimeOps.ADD_DAYS, date, ConstantImpl.create(days));
}
/**
* Start a window function expression
*
* @param expr expression
* @return sum(expr)
*/
public static <T extends Number> WindowOver<T> sum(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), Ops.AggOps.SUM_AGG, expr);
}
/**
* Start a window function expression
*
* @return count()
*/
public static WindowOver<Long> count() {
return new WindowOver<Long>(Long.class, Ops.AggOps.COUNT_ALL_AGG);
}
/**
* Start a window function expression
*
* @param expr expression
* @return count(expr)
*/
public static WindowOver<Long> count(Expression<?> expr) {
return new WindowOver<Long>(Long.class, Ops.AggOps.COUNT_AGG, expr);
}
/**
* Start a window function expression
*
* @param expr expression
* @return count(distinct expr)
*/
public static WindowOver<Long> countDistinct(Expression<?> expr) {
return new WindowOver<Long>(Long.class, Ops.AggOps.COUNT_DISTINCT_AGG, expr);
}
/**
* Start a window function expression
*
* @param expr expression
* @return avg(expr)
*/
public static <T extends Number> WindowOver<T> avg(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), Ops.AggOps.AVG_AGG, expr);
}
/**
* Start a window function expression
*
* @param expr expression
* @return min(expr)
*/
public static <T extends Comparable> WindowOver<T> min(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), Ops.AggOps.MIN_AGG, expr);
}
/**
* Start a window function expression
*
* @param expr expression
* @return max(expr)
*/
public static <T extends Comparable> WindowOver<T> max(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), Ops.AggOps.MAX_AGG, expr);
}
/**
* expr evaluated at the row that is one row after the current row within the partition;
*
* @param expr expression
* @return lead(expr)
*/
public static <T> WindowOver<T> lead(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.LEAD, expr);
}
/**
* expr evaluated at the row that is one row before the current row within the partition
*
* @param expr expression
* @return lag(expr)
*/
public static <T> WindowOver<T> lag(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.LAG, expr);
}
/**
* LISTAGG orders data within each group specified in the ORDER BY clause and then concatenates
* the values of the measure column.
*
* @param expr measure column
* @param delimiter delimiter
* @return listagg(expr, delimiter)
*/
public static WithinGroup<Object> listagg(Expression<?> expr, String delimiter) {
return new WithinGroup<Object>(Object.class, SQLOps.LISTAGG, expr, ConstantImpl.create(delimiter));
}
/**
* NTH_VALUE returns the expr value of the nth row in the window defined by the analytic clause.
* The returned value has the data type of the expr.
*
* @param expr measure expression
* @param n one based row index
* @return nth_value(expr, n)
*/
public static <T> WindowOver<T> nthValue(Expression<T> expr, Number n) {
return nthValue(expr, ConstantImpl.create(n));
}
/**
* NTH_VALUE returns the expr value of the nth row in the window defined by the analytic clause.
* The returned value has the data type of the expr
*
* @param expr measure expression
* @param n one based row index
* @return nth_value(expr, n)
*/
public static <T> WindowOver<T> nthValue(Expression<T> expr, Expression<? extends Number> n) {
return new WindowOver<T>(expr.getType(), SQLOps.NTHVALUE, expr, n);
}
/**
* divides an ordered data set into a number of buckets indicated by expr and assigns the
* appropriate bucket number to each row
*
* @param num bucket size
* @return ntile(num)
*/
@SuppressWarnings("unchecked")
public static <T extends Number & Comparable> WindowOver<T> ntile(T num) {
return new WindowOver<T>((Class<T>) num.getClass(), SQLOps.NTILE, ConstantImpl.create(num));
}
/**
* rank of the current row with gaps; same as row_number of its first peer
*
* @return rank()
*/
public static WindowOver<Long> rank() {
return rank;
}
/**
* As an aggregate function, RANK calculates the rank of a hypothetical row identified by the
* arguments of the function with respect to a given sort specification. The arguments of the
* function must all evaluate to constant expressions within each aggregate group, because they
* identify a single row within each group. The constant argument expressions and the expressions
* in the ORDER BY clause of the aggregate match by position. Therefore, the number of arguments
* must be the same and their types must be compatible.
*
* @param args arguments
* @return rank(args)
*/
@SuppressWarnings("unchecked")
public static WithinGroup<Long> rank(Object... args) {
return rank(convertToExpressions(args));
}
/**
* As an aggregate function, RANK calculates the rank of a hypothetical row identified by the
* arguments of the function with respect to a given sort specification. The arguments of the
* function must all evaluate to constant expressions within each aggregate group, because they
* identify a single row within each group. The constant argument expressions and the expressions
* in the ORDER BY clause of the aggregate match by position. Therefore, the number of arguments
* must be the same and their types must be compatible.
*
* @param args arguments
* @return rank(args)
*/
public static WithinGroup<Long> rank(Expression<?>... args) {
return new WithinGroup<Long>(Long.class, SQLOps.RANK2, args);
}
/**
* rank of the current row without gaps; this function counts peer groups
*
* @return dense_rank()
*/
public static WindowOver<Long> denseRank() {
return denseRank;
}
/**
* As an aggregate function, DENSE_RANK calculates the dense rank of a hypothetical row identified
* by the arguments of the function with respect to a given sort specification. The arguments of
* the function must all evaluate to constant expressions within each aggregate group, because they
* identify a single row within each group. The constant argument expressions and the expressions
* in the order_by_clause of the aggregate match by position. Therefore, the number of arguments
* must be the same and types must be compatible.
*
* @param args arguments
* @return dense_rank(args)
*/
@SuppressWarnings("unchecked")
public static WithinGroup<Long> denseRank(Object... args) {
return denseRank(convertToExpressions(args));
}
/**
* As an aggregate function, DENSE_RANK calculates the dense rank of a hypothetical row identified
* by the arguments of the function with respect to a given sort specification. The arguments of
* the function must all evaluate to constant expressions within each aggregate group, because they
* identify a single row within each group. The constant argument expressions and the expressions
* in the order_by_clause of the aggregate match by position. Therefore, the number of arguments
* must be the same and types must be compatible.
*
* @param args arguments
* @return dense_rank(args)
*/
public static WithinGroup<Long> denseRank(Expression<?>... args) {
return new WithinGroup<Long>(Long.class, SQLOps.DENSERANK2, args);
}
/**
* As an analytic function, for a row r, PERCENT_RANK calculates the rank of r minus 1, divided by
* 1 less than the number of rows being evaluated (the entire query result set or a partition).
*
* @return percent_rank()
*/
public static WindowOver<Double> percentRank() {
return percentRank;
}
/**
* As an aggregate function, PERCENT_RANK calculates, for a hypothetical row r identified by the
* arguments of the function and a corresponding sort specification, the rank of row r minus 1
* divided by the number of rows in the aggregate group. This calculation is made as if the
* hypothetical row r were inserted into the group of rows over which Oracle Database is to
* aggregate. The arguments of the function identify a single hypothetical row within each aggregate
* group. Therefore, they must all evaluate to constant expressions within each aggregate group.
* The constant argument expressions and the expressions in the ORDER BY clause of the aggregate
* match by position. Therefore the number of arguments must be the same and their types must be
* compatible.
*
* @param args arguments
* @return percent_rank(args)
*/
@SuppressWarnings("unchecked")
public static WithinGroup<Double> percentRank(Object... args) {
return percentRank(convertToExpressions(args));
}
/**
* As an aggregate function, PERCENT_RANK calculates, for a hypothetical row r identified by the
* arguments of the function and a corresponding sort specification, the rank of row r minus 1
* divided by the number of rows in the aggregate group. This calculation is made as if the
* hypothetical row r were inserted into the group of rows over which Oracle Database is to aggregate.
* The arguments of the function identify a single hypothetical row within each aggregate group.
* Therefore, they must all evaluate to constant expressions within each aggregate group. The
* constant argument expressions and the expressions in the ORDER BY clause of the aggregate match
* by position. Therefore the number of arguments must be the same and their types must be compatible.
*
* @param args arguments
* @return percent_rank(args)
*/
public static WithinGroup<Double> percentRank(Expression<?>... args) {
return new WithinGroup<Double>(Double.class, SQLOps.PERCENTRANK2, args);
}
/**
* Calculates a percentile based on a continuous distribution of the column value
*
* @param arg argument
* @return percentile_cont(arg)
*/
public static <T extends Number> WithinGroup<T> percentileCont(T arg) {
if (arg.doubleValue() < 0.0 || arg.doubleValue() > 1.0) {
throw new IllegalArgumentException("The percentile value should be a number between 0 and 1");
}
return percentileCont(ConstantImpl.create(arg));
}
/**
* Calculates a percentile based on a continuous distribution of the column value
*
* @param arg argument
* @return percentile_cont(arg)
*/
public static <T extends Number> WithinGroup<T> percentileCont(Expression<T> arg) {
return new WithinGroup<T>(arg.getType(), SQLOps.PERCENTILECONT, arg);
}
/**
* PERCENTILE_DISC is an inverse distribution function that assumes a discrete distribution model.
* It takes a percentile value and a sort specification and returns an element from the set.
* Nulls are ignored in the calculation.
*
* <p>This function takes as an argument any numeric datatype or any nonnumeric datatype that can be
* implicitly converted to a numeric datatype. The function returns the same datatype as the numeric
* datatype of the argument.</p>
*
* @param arg argument
* @return percentile_disc(arg)
*/
public static <T extends Number> WithinGroup<T> percentileDisc(T arg) {
if (arg.doubleValue() < 0.0 || arg.doubleValue() > 1.0) {
throw new IllegalArgumentException("The percentile value should be a number between 0 and 1");
}
return percentileDisc(ConstantImpl.create(arg));
}
/**
* PERCENTILE_DISC is an inverse distribution function that assumes a discrete distribution model.
* It takes a percentile value and a sort specification and returns an element from the set.
* Nulls are ignored in the calculation.
*
* <p>This function takes as an argument any numeric datatype or any nonnumeric datatype that can be
* implicitly converted to a numeric datatype. The function returns the same datatype as the numeric
* datatype of the argument.</p>
*
* @param arg argument
* @return percentile_disc(arg)
*/
public static <T extends Number> WithinGroup<T> percentileDisc(Expression<T> arg) {
return new WithinGroup<T>(arg.getType(), SQLOps.PERCENTILEDISC, arg);
}
/**
* REGR_SLOPE returns the slope of the line
*
* @param arg1 first arg
* @param arg2 second arg
* @return regr_slope(arg1, arg2)
*/
public static WindowOver<Double> regrSlope(Expression<? extends Number> arg1, Expression<? extends Number> arg2) {
return new WindowOver<Double>(Double.class, SQLOps.REGR_SLOPE, arg1, arg2);
}
/**
* REGR_INTERCEPT returns the y-intercept of the regression line.
*
* @param arg1 first arg
* @param arg2 second arg
* @return regr_intercept(arg1, arg2)
*/
public static WindowOver<Double> regrIntercept(Expression<? extends Number> arg1, Expression<? extends Number> arg2) {
return new WindowOver<Double>(Double.class, SQLOps.REGR_INTERCEPT, arg1, arg2);
}
/**
* REGR_COUNT returns an integer that is the number of non-null number pairs used to fit the regression line.
*
* @param arg1 first arg
* @param arg2 second arg
* @return regr_count(arg1, arg2)
*/
public static WindowOver<Double> regrCount(Expression<? extends Number> arg1, Expression<? extends Number> arg2) {
return new WindowOver<Double>(Double.class, SQLOps.REGR_COUNT, arg1, arg2);
}
/**
* REGR_R2 returns the coefficient of determination (also called R-squared or goodness of fit) for the regression.
*
* @param arg1 first arg
* @param arg2 second arg
* @return regr_r2(arg1, arg2)
*/
public static WindowOver<Double> regrR2(Expression<? extends Number> arg1, Expression<? extends Number> arg2) {
return new WindowOver<Double>(Double.class, SQLOps.REGR_R2, arg1, arg2);
}
/**
* REGR_AVGX evaluates the average of the independent variable (arg2) of the regression line.
*
* @param arg1 first arg
* @param arg2 second arg
* @return regr_avgx(arg1, arg2)
*/
public static WindowOver<Double> regrAvgx(Expression<? extends Number> arg1, Expression<? extends Number> arg2) {
return new WindowOver<Double>(Double.class, SQLOps.REGR_AVGX, arg1, arg2);
}
/**
* REGR_AVGY evaluates the average of the dependent variable (arg1) of the regression line.
*
* @param arg1 first arg
* @param arg2 second arg
* @return regr_avgy(arg1, arg2)
*/
public static WindowOver<Double> regrAvgy(Expression<? extends Number> arg1, Expression<? extends Number> arg2) {
return new WindowOver<Double>(Double.class, SQLOps.REGR_AVGY, arg1, arg2);
}
/**
* REGR_SXX makes the following computation after the elimination of null (arg1, arg2) pairs:
*
* <p>{@code REGR_COUNT(arg1, arg2) * VAR_POP(arg2)}</p>
*
* @param arg1 first arg
* @param arg2 second arg
* @return regr_sxx(arg1, arg2)
*/
public static WindowOver<Double> regrSxx(Expression<? extends Number> arg1, Expression<? extends Number> arg2) {
return new WindowOver<Double>(Double.class, SQLOps.REGR_SXX, arg1, arg2);
}
/**
* REGR_SYY makes the following computation after the elimination of null (arg1, arg2) pairs:
*
* <p>{@code REGR_COUNT(arg1, arg2) * VAR_POP(arg1)}</p>
*
* @param arg1 first arg
* @param arg2 second arg
* @return regr_syy(arg1, arg2)
*/
public static WindowOver<Double> regrSyy(Expression<? extends Number> arg1, Expression<? extends Number> arg2) {
return new WindowOver<Double>(Double.class, SQLOps.REGR_SYY, arg1, arg2);
}
/**
* REGR_SXY makes the following computation after the elimination of null (arg1, arg2) pairs:
*
* <p>REGR_COUNT(arg1, arg2) * COVAR_POP(arg1, arg2)</p>
*
* @param arg1 first arg
* @param arg2 second arg
* @return regr_sxy(arg1, arg2)
*/
public static WindowOver<Double> regrSxy(Expression<? extends Number> arg1, Expression<? extends Number> arg2) {
return new WindowOver<Double>(Double.class, SQLOps.REGR_SXY, arg1, arg2);
}
/**
* CUME_DIST calculates the cumulative distribution of a value in a group of values.
*
* @return cume_dist()
*/
public static WindowOver<Double> cumeDist() {
return cumeDist;
}
/**
* As an aggregate function, CUME_DIST calculates, for a hypothetical row r identified by the
* arguments of the function and a corresponding sort specification, the relative position of row
* r among the rows in the aggregation group. Oracle makes this calculation as if the hypothetical
* row r were inserted into the group of rows to be aggregated over. The arguments of the function
* identify a single hypothetical row within each aggregate group. Therefore, they must all
* evaluate to constant expressions within each aggregate group. The constant argument expressions
* and the expressions in the ORDER BY clause of the aggregate match by position. Therefore,
* the number of arguments must be the same and their types must be compatible.
*
* @param args arguments
* @return cume_dist(args)
*/
@SuppressWarnings("unchecked")
public static WithinGroup<Double> cumeDist(Object... args) {
return cumeDist(convertToExpressions(args));
}
/**
* As an aggregate function, CUME_DIST calculates, for a hypothetical row r identified by the
* arguments of the function and a corresponding sort specification, the relative position of row
* r among the rows in the aggregation group. Oracle makes this calculation as if the hypothetical
* row r were inserted into the group of rows to be aggregated over. The arguments of the function
* identify a single hypothetical row within each aggregate group. Therefore, they must all
* evaluate to constant expressions within each aggregate group. The constant argument expressions
* and the expressions in the ORDER BY clause of the aggregate match by position. Therefore,
* the number of arguments must be the same and their types must be compatible.
*
* @param args arguments
* @return cume_dist(args)
*/
public static WithinGroup<Double> cumeDist(Expression<?>... args) {
return new WithinGroup<Double>(Double.class, SQLOps.CUMEDIST2, args);
}
/**
* CORR returns the coefficient of correlation of a set of number pairs.
*
* @param expr1 first arg
* @param expr2 second arg
* @return corr(expr1, expr2)
*/
public static WindowOver<Double> corr(Expression<? extends Number> expr1, Expression<? extends Number> expr2) {
return new WindowOver<Double>(Double.class, SQLOps.CORR, expr1, expr2);
}
/**
* CORR returns the coefficient of correlation of a set of number pairs.
*
* @param expr1 first arg
* @param expr2 second arg
* @return corr(expr1, expr2)
*/
public static WindowOver<Double> covarPop(Expression<? extends Number> expr1, Expression<? extends Number> expr2) {
return new WindowOver<Double>(Double.class, SQLOps.COVARPOP, expr1, expr2);
}
/**
* CORR returns the coefficient of correlation of a set of number pairs.
*
* @param expr1 first arg
* @param expr2 second arg
* @return corr(expr1, expr2)
*/
public static WindowOver<Double> covarSamp(Expression<? extends Number> expr1, Expression<? extends Number> expr2) {
return new WindowOver<Double>(Double.class, SQLOps.COVARSAMP, expr1, expr2);
}
/**
* computes the ratio of a value to the sum of a set of values. If expr evaluates to null,
* then the ratio-to-report value also evaluates to null.
*
* @return ratio_to_report(expr)
*/
public static <T> WindowOver<T> ratioToReport(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.RATIOTOREPORT, expr);
}
/**
* number of the current row within its partition, counting from 1
*
* @return row_number()
*/
public static WindowOver<Long> rowNumber() {
return rowNumber;
}
/**
* returns the sample standard deviation of expr, a set of numbers.
*
* @param expr argument
* @return stddev(expr)
*/
public static <T extends Number> WindowOver<T> stddev(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.STDDEV, expr);
}
/**
* returns the sample standard deviation of expr, a set of numbers.
*
* @param expr argument
* @return stddev(distinct expr)
*/
public static <T extends Number> WindowOver<T> stddevDistinct(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.STDDEV_DISTINCT, expr);
}
/**
* returns the population standard deviation and returns the square root of the population variance.
*
* @param expr argument
* @return stddev_pop(expr)
*/
public static <T extends Number> WindowOver<T> stddevPop(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.STDDEVPOP, expr);
}
/**
* returns the cumulative sample standard deviation and returns the square root of the sample variance.
*
* @param expr argument
* @return stddev_samp(expr)
*/
public static <T extends Number> WindowOver<T> stddevSamp(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.STDDEVSAMP, expr);
}
/**
* returns the variance of expr
*
* @param expr argument
* @return variance(expr)
*/
public static <T extends Number> WindowOver<T> variance(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.VARIANCE, expr);
}
/**
* returns the population variance of a set of numbers after discarding the nulls in this set.
*
* @param expr argument
* @return var_pop(expr)
*/
public static <T extends Number> WindowOver<T> varPop(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.VARPOP, expr);
}
/**
* returns the sample variance of a set of numbers after discarding the nulls in this set.
*
* @param expr argument
* @return var_samp(expr)
*/
public static <T extends Number> WindowOver<T> varSamp(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.VARSAMP, expr);
}
/**
* returns value evaluated at the row that is the first row of the window frame
*
* @param expr argument
* @return first_value(expr)
*/
public static <T> WindowOver<T> firstValue(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.FIRSTVALUE, expr);
}
/**
* returns value evaluated at the row that is the last row of the window frame
*
* @param expr argument
* @return last_value(expr)
*/
public static <T> WindowOver<T> lastValue(Expression<T> expr) {
return new WindowOver<T>(expr.getType(), SQLOps.LASTVALUE, expr);
}
/**
* Get the rhs leftmost characters of lhs
*
* @param lhs string
* @param rhs character amount
* @return rhs leftmost characters
*/
public static StringExpression left(Expression<String> lhs, int rhs) {
return left(lhs, ConstantImpl.create(rhs));
}
/**
* Get the rhs rightmost characters of lhs
*
* @param lhs string
* @param rhs character amount
* @return rhs rightmost characters
*/
public static StringExpression right(Expression<String> lhs, int rhs) {
return right(lhs, ConstantImpl.create(rhs));
}
/**
* Get the rhs leftmost characters of lhs
*
* @param lhs string
* @param rhs character amount
* @return rhs leftmost characters
*/
public static StringExpression left(Expression<String> lhs, Expression<Integer> rhs) {
return Expressions.stringOperation(Ops.StringOps.LEFT, lhs, rhs);
}
/**
* Get the rhs leftmost characters of lhs
*
* @param lhs string
* @param rhs character amount
* @return rhs rightmost characters
*/
public static StringExpression right(Expression<String> lhs, Expression<Integer> rhs) {
return Expressions.stringOperation(Ops.StringOps.RIGHT, lhs, rhs);
}
/**
* Get a group_concat(expr) expression
*
* @param expr expression to be aggregated
* @return group_concat(expr)
*/
public static StringExpression groupConcat(Expression<String> expr) {
return Expressions.stringOperation(SQLOps.GROUP_CONCAT, expr);
}
/**
* Get a group_concat(expr, separator) expression
*
* @param expr expression to be aggregated
* @param separator separator string
* @return group_concat(expr, separator)
*/
public static StringExpression groupConcat(Expression<String> expr, String separator) {
return Expressions.stringOperation(SQLOps.GROUP_CONCAT2, expr, Expressions.constant(separator));
}
private SQLExpressions() { }
}