Unverified 提交 d0c4469a authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1408 from katzyn/aggregate

Add MODE() aggregate function
......@@ -3416,6 +3416,27 @@ Aggregates are only allowed in select statements.
MEDIAN(X)
"
"Functions (Aggregate)","MODE","
{ MODE( value ) [ ORDER BY expression [ ASC | DESC ] ] }
| { MODE() WITHIN GROUP(ORDER BY expression [ ASC | DESC ]) }
[ FILTER ( WHERE expression ) ]
","
Returns the value that occurs with the greatest frequency.
If there are multiple values with the same frequency only one value will be returned.
In this situation value will be chosen based on optional ORDER BY clause
that should specify exactly the same expression as argument of this function.
Use ascending order to get smallest value or descending order to get largest value
from multiple values with the same frequency.
If this clause is not specified the exact chosen value is not determined in this situation.
NULL values are ignored in the calculation.
If no rows are selected, the result is NULL.
Aggregates are only allowed in select statements.
","
MODE(X)
MODE(X ORDER BY X)
MODE() WITHIN GROUP(ORDER BY X)
"
"Functions (Numeric)","ABS","
ABS ( { numeric } )
","
......
......@@ -21,6 +21,14 @@ Change Log
<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #1407: Add a MODE() aggregate function
</li>
<li>PR #1402: Duplicate conditions in column check constraint
</li>
<li>PR #1399: Add more subclasses of SQLException and use it for some error codes
</li>
<li>PR #1397: Add DATEADD return type detection
</li>
<li>Issue #1393: Add INFORMATION_SCHEMA.COLUMNS.IS_VISIBLE
</li>
<li>PR #1392: Some refactoring and assorted minor optimizations
......
......@@ -402,6 +402,17 @@ public class ErrorCode {
*/
public static final int COLUMN_NOT_FOUND_1 = 42122;
/**
* The error with code <code>42123</code> is thrown when
* identical expressions should be used, but different
* exceptions were found.
* Example:
* <pre>
* SELECT MODE(A ORDER BY B) FROM TEST;
* </pre>
*/
public static final int IDENTICAL_EXPRESSIONS_SHOULD_BE_USED = 42131;
// 0A: feature not supported
// HZ: remote database access
......@@ -2068,6 +2079,7 @@ public class ErrorCode {
case INDEX_NOT_FOUND_1: return "42S12";
case DUPLICATE_COLUMN_NAME_1: return "42S21";
case COLUMN_NOT_FOUND_1: return "42S22";
case IDENTICAL_EXPRESSIONS_SHOULD_BE_USED: return "42S31";
// 0A: feature not supported
......
......@@ -145,8 +145,6 @@ import org.h2.engine.SysProperties;
import org.h2.engine.User;
import org.h2.engine.UserAggregate;
import org.h2.engine.UserDataType;
import org.h2.expression.Aggregate;
import org.h2.expression.Aggregate.AggregateType;
import org.h2.expression.Alias;
import org.h2.expression.BinaryOperation;
import org.h2.expression.BinaryOperation.OpType;
......@@ -163,7 +161,6 @@ import org.h2.expression.ExpressionColumn;
import org.h2.expression.ExpressionList;
import org.h2.expression.Function;
import org.h2.expression.FunctionCall;
import org.h2.expression.JavaAggregate;
import org.h2.expression.JavaFunction;
import org.h2.expression.Parameter;
import org.h2.expression.Rownum;
......@@ -174,6 +171,9 @@ import org.h2.expression.UnaryOperation;
import org.h2.expression.ValueExpression;
import org.h2.expression.Variable;
import org.h2.expression.Wildcard;
import org.h2.expression.aggregate.Aggregate;
import org.h2.expression.aggregate.Aggregate.AggregateType;
import org.h2.expression.aggregate.JavaAggregate;
import org.h2.index.Index;
import org.h2.message.DbException;
import org.h2.result.SortOrder;
......@@ -1209,12 +1209,7 @@ public class Parser {
}
private int parseSortType() {
int sortType = 0;
if (readIf("ASC")) {
// ignore
} else if (readIf("DESC")) {
sortType = SortOrder.DESCENDING;
}
int sortType = parseSimpleSortType();
if (readIf("NULLS")) {
if (readIf("FIRST")) {
sortType |= SortOrder.NULLS_FIRST;
......@@ -1226,6 +1221,13 @@ public class Parser {
return sortType;
}
private int parseSimpleSortType() {
if (!readIf("ASC") && readIf("DESC")) {
return SortOrder.DESCENDING;
}
return SortOrder.ASCENDING;
}
private String[] parseColumnList() {
ArrayList<String> columns = Utils.newSmallArrayList();
do {
......@@ -2916,40 +2918,35 @@ public class Parser {
}
currentSelect.setGroupQuery();
Aggregate r;
if (aggregateType == AggregateType.COUNT) {
switch (aggregateType) {
case COUNT:
if (readIf(ASTERISK)) {
r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect,
false);
r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect, false);
} else {
boolean distinct = readIf(DISTINCT);
Expression on = readExpression();
if (on instanceof Wildcard && !distinct) {
// PostgreSQL compatibility: count(t.*)
r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect,
false);
r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect, false);
} else {
r = new Aggregate(AggregateType.COUNT, on, currentSelect,
distinct);
r = new Aggregate(AggregateType.COUNT, on, currentSelect, distinct);
}
}
} else if (aggregateType == AggregateType.GROUP_CONCAT) {
break;
case GROUP_CONCAT: {
boolean distinct = readIf(DISTINCT);
if (equalsToken("GROUP_CONCAT", aggregateName)) {
r = new Aggregate(AggregateType.GROUP_CONCAT,
readExpression(), currentSelect, distinct);
r = new Aggregate(AggregateType.GROUP_CONCAT, readExpression(), currentSelect, distinct);
if (readIf(ORDER)) {
read("BY");
r.setOrderByList(parseSimpleOrderList());
}
if (readIf("SEPARATOR")) {
r.setGroupConcatSeparator(readExpression());
}
} else if (equalsToken("STRING_AGG", aggregateName)) {
// PostgreSQL compatibility: string_agg(expression, delimiter)
r = new Aggregate(AggregateType.GROUP_CONCAT,
readExpression(), currentSelect, distinct);
r = new Aggregate(AggregateType.GROUP_CONCAT, readExpression(), currentSelect, distinct);
read(COMMA);
r.setGroupConcatSeparator(readExpression());
if (readIf(ORDER)) {
......@@ -2959,19 +2956,47 @@ public class Parser {
} else {
r = null;
}
} else if (aggregateType == AggregateType.ARRAY_AGG) {
break;
}
case ARRAY_AGG: {
boolean distinct = readIf(DISTINCT);
r = new Aggregate(AggregateType.ARRAY_AGG,
readExpression(), currentSelect, distinct);
r = new Aggregate(AggregateType.ARRAY_AGG, readExpression(), currentSelect, distinct);
if (readIf(ORDER)) {
read("BY");
r.setOrderByList(parseSimpleOrderList());
}
} else {
break;
}
case MODE: {
if (readIf(CLOSE_PAREN)) {
read("WITHIN");
read(GROUP);
read(OPEN_PAREN);
read(ORDER);
read("BY");
Expression expr = readExpression();
r = new Aggregate(AggregateType.MODE, expr, currentSelect, false);
setModeAggOrder(r, expr);
} else {
Expression expr = readExpression();
r = new Aggregate(aggregateType, expr, currentSelect, false);
if (readIf(ORDER)) {
read("BY");
Expression expr2 = readExpression();
String sql = expr.getSQL(), sql2 = expr2.getSQL();
if (!sql.equals(sql2)) {
throw DbException.getSyntaxError(ErrorCode.IDENTICAL_EXPRESSIONS_SHOULD_BE_USED, sqlCommand,
lastParseIndex, sql, sql2);
}
setModeAggOrder(r, expr);
}
}
break;
}
default:
boolean distinct = readIf(DISTINCT);
r = new Aggregate(aggregateType, readExpression(), currentSelect,
distinct);
r = new Aggregate(aggregateType, readExpression(), currentSelect, distinct);
break;
}
read(CLOSE_PAREN);
if (r != null) {
......@@ -2980,6 +3005,15 @@ public class Parser {
return r;
}
private void setModeAggOrder(Aggregate r, Expression expr) {
ArrayList<SelectOrderBy> orderList = new ArrayList<>(1);
SelectOrderBy order = new SelectOrderBy();
order.expression = expr;
order.sortType = parseSimpleSortType();
orderList.add(order);
r.setOrderByList(orderList);
}
private ArrayList<SelectOrderBy> parseSimpleOrderList() {
ArrayList<SelectOrderBy> orderList = Utils.newSmallArrayList();
do {
......
......@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
package org.h2.expression.aggregate;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -13,6 +13,9 @@ import org.h2.api.ErrorCode;
import org.h2.command.dml.Select;
import org.h2.command.dml.SelectOrderBy;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn;
import org.h2.expression.ExpressionVisitor;
import org.h2.index.Cursor;
import org.h2.index.Index;
import org.h2.message.DbException;
......@@ -129,10 +132,16 @@ public class Aggregate extends Expression {
* The aggregate type for MEDIAN(expression).
*/
MEDIAN,
/**
* The aggregate type for ARRAY_AGG(expression).
*/
ARRAY_AGG
ARRAY_AGG,
/**
* The aggregate type for MODE(expression).
*/
MODE,
}
private static final HashMap<String, AggregateType> AGGREGATES = new HashMap<>(64);
......@@ -200,6 +209,9 @@ public class Aggregate extends Expression {
addAggregate("BIT_AND", AggregateType.BIT_AND);
addAggregate("MEDIAN", AggregateType.MEDIAN);
addAggregate("ARRAY_AGG", AggregateType.ARRAY_AGG);
addAggregate("MODE", AggregateType.MODE);
// Oracle compatibility
addAggregate("STATS_MODE", AggregateType.MODE);
}
private static void addAggregate(String name, AggregateType type) {
......@@ -372,7 +384,8 @@ public class Aggregate extends Expression {
data = AggregateData.create(type);
select.setCurrentGroupExprData(this, data);
}
if (type == AggregateType.GROUP_CONCAT) {
switch (type) {
case GROUP_CONCAT: {
Value[] array = ((AggregateDataCollecting) data).getArray();
if (array == null) {
return ValueNull.INSTANCE;
......@@ -399,7 +412,8 @@ public class Aggregate extends Expression {
buff.append(s);
}
return ValueString.get(buff.toString());
} else if (type == AggregateType.ARRAY_AGG) {
}
case ARRAY_AGG: {
Value[] array = ((AggregateDataCollecting) data).getArray();
if (array == null) {
return ValueNull.INSTANCE;
......@@ -414,7 +428,15 @@ public class Aggregate extends Expression {
}
return ValueArray.get(array);
}
return data.getValue(session.getDatabase(), dataType, distinct);
case MODE:
if (orderByList != null) {
return ((AggregateDataMode) data).getOrderedValue(session.getDatabase(), dataType,
(orderByList.get(0).sortType & SortOrder.DESCENDING) != 0);
}
//$FALL-THROUGH$
default:
return data.getValue(session.getDatabase(), dataType, distinct);
}
}
@Override
......@@ -503,6 +525,7 @@ public class Aggregate extends Expression {
case MIN:
case MAX:
case MEDIAN:
case MODE:
break;
case STDDEV_POP:
case STDDEV_SAMP:
......@@ -673,6 +696,9 @@ public class Aggregate extends Expression {
break;
case ARRAY_AGG:
return getSQLArrayAggregate();
case MODE:
text = "MODE";
break;
default:
throw DbException.throwInternalError("type=" + type);
}
......
......@@ -3,10 +3,10 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
package org.h2.expression.aggregate;
import org.h2.engine.Database;
import org.h2.expression.Aggregate.AggregateType;
import org.h2.expression.aggregate.Aggregate.AggregateType;
import org.h2.value.Value;
/**
......@@ -35,6 +35,8 @@ abstract class AggregateData {
return new AggregateDataHistogram();
case MEDIAN:
return new AggregateDataMedian();
case MODE:
return new AggregateDataMode();
default:
return new AggregateDataDefault(aggregateType);
}
......
......@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
package org.h2.expression.aggregate;
import java.util.ArrayList;
import java.util.Collection;
......
......@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
package org.h2.expression.aggregate;
import org.h2.engine.Database;
import org.h2.util.ValueHashMap;
......
......@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
package org.h2.expression.aggregate;
import org.h2.engine.Database;
import org.h2.message.DbException;
......
......@@ -3,10 +3,10 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
package org.h2.expression.aggregate;
import org.h2.engine.Database;
import org.h2.expression.Aggregate.AggregateType;
import org.h2.expression.aggregate.Aggregate.AggregateType;
import org.h2.message.DbException;
import org.h2.util.ValueHashMap;
import org.h2.value.DataType;
......
......@@ -3,11 +3,11 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
package org.h2.expression.aggregate;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Mode;
......@@ -21,37 +21,35 @@ import org.h2.value.ValueLong;
* Data stored while calculating a HISTOGRAM aggregate.
*/
class AggregateDataHistogram extends AggregateData {
private long count;
private ValueHashMap<AggregateDataHistogram> distinctValues;
private ValueHashMap<LongDataCounter> distinctValues;
@Override
void add(Database database, int dataType, boolean distinct, Value v) {
if (distinctValues == null) {
distinctValues = ValueHashMap.newInstance();
}
AggregateDataHistogram a = distinctValues.get(v);
LongDataCounter a = distinctValues.get(v);
if (a == null) {
if (distinctValues.size() < Constants.SELECTIVITY_DISTINCT_COUNT) {
a = new AggregateDataHistogram();
distinctValues.put(v, a);
if (distinctValues.size() >= Constants.SELECTIVITY_DISTINCT_COUNT) {
return;
}
a = new LongDataCounter();
distinctValues.put(v, a);
}
if (a != null) {
a.count++;
}
a.count++;
}
@Override
Value getValue(Database database, int dataType, boolean distinct) {
if (distinct) {
count = 0;
groupDistinct(database, dataType);
if (distinctValues == null) {
return ValueArray.get(new Value[0]).convertTo(dataType);
}
ValueArray[] values = new ValueArray[distinctValues.size()];
int i = 0;
for (Map.Entry<Value,AggregateDataHistogram> entry : distinctValues.entries()) {
AggregateDataHistogram d = entry.getValue();
values[i] = ValueArray.get(new Value[] { entry.getKey(), ValueLong.get(d.count) });
for (Entry<Value, LongDataCounter> entry : distinctValues.entries()) {
LongDataCounter d = entry.getValue();
values[i] = ValueArray.get(new Value[] { entry.getKey(), ValueLong.get(distinct ? 1L : d.count) });
i++;
}
final Mode mode = database.getMode();
......@@ -64,18 +62,7 @@ class AggregateDataHistogram extends AggregateData {
return a1.compareTo(a2, mode, compareMode);
}
});
Value v = ValueArray.get(values);
return v.convertTo(dataType);
}
private void groupDistinct(Database database, int dataType) {
if (distinctValues == null) {
return;
}
count = 0;
for (Value v : distinctValues.keys()) {
add(database, dataType, false, v);
}
return ValueArray.get(values).convertTo(dataType);
}
}
......@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
package org.h2.expression.aggregate;
import java.math.BigDecimal;
import java.util.ArrayList;
......@@ -14,6 +14,8 @@ import org.h2.engine.Database;
import org.h2.engine.Mode;
import org.h2.engine.Session;
import org.h2.engine.SysProperties;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn;
import org.h2.index.Cursor;
import org.h2.index.Index;
import org.h2.result.SearchRow;
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression.aggregate;
import java.util.Map.Entry;
import org.h2.engine.Database;
import org.h2.util.ValueHashMap;
import org.h2.value.Value;
import org.h2.value.ValueNull;
/**
* Data stored while calculating a MODE aggregate.
*/
class AggregateDataMode extends AggregateData {
private ValueHashMap<LongDataCounter> distinctValues;
@Override
void add(Database database, int dataType, boolean distinct, Value v) {
if (v == ValueNull.INSTANCE) {
return;
}
if (distinctValues == null) {
distinctValues = ValueHashMap.newInstance();
}
LongDataCounter a = distinctValues.get(v);
if (a == null) {
a = new LongDataCounter();
distinctValues.put(v, a);
}
a.count++;
}
@Override
Value getValue(Database database, int dataType, boolean distinct) {
Value v = ValueNull.INSTANCE;
if (distinctValues != null) {
long count = 0L;
for (Entry<Value, LongDataCounter> entry : distinctValues.entries()) {
long c = entry.getValue().count;
if (c > count) {
v = entry.getKey();
count = c;
}
}
}
return v.convertTo(dataType);
}
Value getOrderedValue(Database database, int dataType, boolean desc) {
Value v = ValueNull.INSTANCE;
if (distinctValues != null) {
long count = 0L;
for (Entry<Value, LongDataCounter> entry : distinctValues.entries()) {
long c = entry.getValue().count;
if (c > count) {
v = entry.getKey();
count = c;
} else if (c == count) {
Value v2 = entry.getKey();
int cmp = database.compareTypeSafe(v, v2);
if (desc) {
if (cmp >= 0) {
continue;
}
} else if (cmp <= 0) {
continue;
}
v = v2;
}
}
}
return v.convertTo(dataType);
}
}
......@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
package org.h2.expression.aggregate;
import org.h2.engine.Constants;
import org.h2.engine.Database;
......
......@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression;
package org.h2.expression.aggregate;
import java.sql.Connection;
import java.sql.SQLException;
......@@ -13,6 +13,8 @@ import org.h2.command.Parser;
import org.h2.command.dml.Select;
import org.h2.engine.Session;
import org.h2.engine.UserAggregate;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionVisitor;
import org.h2.message.DbException;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.expression.aggregate;
/**
* Counter.
*/
final class LongDataCounter {
/**
* The value.
*/
long count;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0, Version 1.0,
and under the Eclipse Public License, Version 1.0
Initial Developer: H2 Group
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Javadoc package documentation
</title></head><body style="font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;"><p>
Aggregate functions.
</p></body></html>
\ No newline at end of file
......@@ -237,6 +237,22 @@ public class DbException extends RuntimeException {
null, sql, message));
}
/**
* Create a syntax error exception for a specific error code.
*
* @param errorCode the error code
* @param sql the SQL statement
* @param index the position of the error in the SQL statement
* @param params the list of parameters of the message
* @return the exception
*/
public static DbException getSyntaxError(int errorCode, String sql, int index, String... params) {
sql = StringUtils.addAsterisk(sql, index);
String sqlstate = ErrorCode.getState(errorCode);
String message = translate(sqlstate, params);
return new DbException(getJdbcSQLException(message, sql, sqlstate, errorCode, null, null));
}
/**
* Gets a SQL exception meaning this feature is not supported.
*
......
......@@ -31,7 +31,7 @@
42S12=Index {0} nenalezen
42S21=Duplicitní název sloupce {0}
42S22=Sloupec {0} nenalezen
42S32=Nastavení {0} nenalezeno
42S31=#Identical expressions should be used; expected {0}, found {1}
57014=Příkaz byl zrušen nebo připojení vypršelo
90000=Funkce {0} musí vracet výsledek
90001=Metoda neumožňuje dotazování. Použijte execute nebo executeQuery namísto executeUpdate
......
......@@ -31,7 +31,7 @@
42S12=Index {0} nicht gefunden
42S21=Doppelter Feldname {0}
42S22=Feld {0} nicht gefunden
42S32=Einstellung {0} nicht gefunden
42S31=#Identical expressions should be used; expected {0}, found {1}
57014=Befehl wurde abgebrochen oder das Session-Timeout ist abgelaufen
90000=Funktion {0} muss Zeilen zurückgeben
90001=Methode nicht zulässig für eine Abfrage. Erlaubt sind execute oder executeQuery, nicht jedoch executeUpdate
......
......@@ -31,7 +31,7 @@
42S12=Index {0} not found
42S21=Duplicate column name {0}
42S22=Column {0} not found
42S32=Setting {0} not found
42S31=Identical expressions should be used; expected {0}, found {1}
57014=Statement was canceled or the session timed out
90000=Function {0} must return a result set
90001=Method is not allowed for a query. Use execute or executeQuery instead of executeUpdate
......
......@@ -31,7 +31,7 @@
42S12=Indice {0} no encontrado
42S21=Nombre de columna Duplicada {0}
42S22=Columna {0} no encontrada
42S32=Setting {0} no encontrado
42S31=#Identical expressions should be used; expected {0}, found {1}
57014=Ls sentencia fue cancelado ó la sesión expiró por tiempo vencido
90000=Función {0} debe devolver un set de resultados (ResultSet)
90001=Metodo no permitido en un query. Use execute ó executeQuery en lugar de executeUpdate
......
......@@ -31,7 +31,7 @@
42S12=Index {0} non trouvé
42S21=Duplication du nom de colonnes {0}
42S22=Colonne {0} non trouvée
42S32=Paramètre {0} non trouvé
42S31=#Identical expressions should be used; expected {0}, found {1}
57014=L'instruction a été annulée ou la session a expiré
90000=La fonction {0} doit retourner résultat
90001=Methode non autorisée pour une requête. Utilisez execute ou executeQuery à la place d'executeUpdate
......
......@@ -31,7 +31,7 @@
42S12=インデックス {0} が見つかりません
42S21=列名 {0} が重複しています
42S22=列 {0} が見つかりません
42S32=設定 {0} が見つかりません
42S31=#Identical expressions should be used; expected {0}, found {1}
57014=ステートメントがキャンセルされたか、セッションがタイムアウトしました
90000=関数 {0} はリザルトセットを返さなければなりません
90001=メソッドはクエリをサポートしていません。executeUpdateのかわりに、excute、またはexecuteQueryを使用してください
......
......@@ -31,7 +31,7 @@
42S12=Indeks {0} nie istnieje
42S21=Zduplikowana nazwa kolumny {0}
42S22=Kolumna {0} nie istnieje
42S32=Ustawienie {0} nie istnieje
42S31=#Identical expressions should be used; expected {0}, found {1}
57014=Kwerenda została anulowana albo sesja wygasła
90000=Funkcja {0} musi zwrócić dane
90001=Metoda nie jest dozwolona w kwerendzie
......
......@@ -31,7 +31,7 @@
42S12=índice {0} não foi encontrado
42S21=Nome duplicado da coluna {0}
42S22=Coluna {0} não foi encontrada
42S32=Definição {0} não foi encontrada
42S31=#Identical expressions should be used; expected {0}, found {1}
57014=#Statement was canceled or the session timed out
90000=Função {0} deve retornar algum resultado
90001=O método não esta hábilitado para consulta. Use o execute ou o executeQuery em vez de executeUpdate
......
......@@ -31,7 +31,7 @@
42S12=Индекс {0} не найден
42S21=Повтор имени столбца {0}
42S22=Столбец {0} не найден
42S32=Настройка {0} не найдена
42S31=Должны использоваться идентичные выражения; ожидалось {0}, получено {1}
57014=Запрос был отменен или закончилось время ожидания сессии
90000=Функция {0} должна возвращать набор записей
90001=Метод не разрешен для запросов. Используйте execute или executeQuery вместо executeUpdate
......
......@@ -31,7 +31,7 @@
42S12=Index {0} nenájdený
42S21=Duplicitné meno stĺpca {0}
42S22=Stĺpec {0} nenájdený
42S32=Nastavenie {0} nenájdené
42S31=#Identical expressions should be used; expected {0}, found {1}
57014=Príkaz bol zrušený alebo vypršal časový limit sedenia
90000=Funkcia {0} musí vracať výsledok (result set)
90001=Metóda nie je povolená pre dopyt (query). Použite execute alebo executeQuery namiesto executeUpdate
......
......@@ -31,7 +31,7 @@
42S12=找不到索引 {0}
42S21=重复的字段: {0}
42S22=找不到字段 {0}
42S32=找不到设置 {0}
42S31=#Identical expressions should be used; expected {0}, found {1}
57014=语句已取消执行或会话已过期
90000={0} 函数必须返回一个结果集
90001=不允许在查询内使用的方法,使用execute 或 executeQuery 代替 executeUpdate
......
......@@ -137,7 +137,7 @@ public class TestScript extends TestDb {
testScript("other/" + s + ".sql");
}
for (String s : new String[] { "avg", "bit-and", "bit-or", "count",
"group-concat", "max", "median", "min", "selectivity", "stddev-pop",
"group-concat", "max", "median", "min", "mode", "selectivity", "stddev-pop",
"stddev-samp", "sum", "var-pop", "var-samp", "array-agg" }) {
testScript("functions/aggregate/" + s + ".sql");
}
......
-- Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
CREATE TABLE TEST(V INT);
> ok
SELECT MODE(V) FROM TEST;
>> null
SELECT MODE(DISTINCT V) FROM TEST;
> exception SYNTAX_ERROR_2
INSERT INTO TEST VALUES (NULL);
> update count: 1
SELECT MODE(V) FROM TEST;
>> null
INSERT INTO TEST VALUES (1), (2), (3), (1), (2), (1);
> update count: 6
SELECT MODE(V), MODE(V) FILTER (WHERE (V > 1)), MODE(V) FILTER (WHERE (V < 0)) FROM TEST;
> MODE(V) MODE(V) FILTER (WHERE (V > 1)) MODE(V) FILTER (WHERE (V < 0))
> ------- ------------------------------ ------------------------------
> 1 2 null
> rows: 1
-- Oracle compatibility
SELECT STATS_MODE(V) FROM TEST;
>> 1
INSERT INTO TEST VALUES (2), (3), (3);
> update count: 3
SELECT MODE(V ORDER BY V) FROM TEST;
>> 1
SELECT MODE(V ORDER BY V ASC) FROM TEST;
>> 1
SELECT MODE(V ORDER BY V DESC) FROM TEST;
>> 3
SELECT MODE(V ORDER BY V + 1) FROM TEST;
> exception IDENTICAL_EXPRESSIONS_SHOULD_BE_USED
SELECT MODE() WITHIN GROUP(ORDER BY V) FROM TEST;
>> 1
SELECT MODE() WITHIN GROUP(ORDER BY V ASC) FROM TEST;
>> 1
SELECT MODE() WITHIN GROUP(ORDER BY V DESC) FROM TEST;
>> 3
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论