Unverified 提交 c812500b authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #865 from katzyn/filter

Add optional FILTER to aggregates
...@@ -2636,7 +2636,7 @@ GEOMETRY ...@@ -2636,7 +2636,7 @@ GEOMETRY
" "
"Functions (Aggregate)","AVG"," "Functions (Aggregate)","AVG","
AVG ( [ DISTINCT ] { numeric } ) AVG ( [ DISTINCT ] { numeric } ) [ FILTER ( WHERE expression ) ]
"," ","
The average (mean) value. The average (mean) value.
If no rows are selected, the result is NULL. If no rows are selected, the result is NULL.
...@@ -2647,7 +2647,7 @@ AVG(X) ...@@ -2647,7 +2647,7 @@ AVG(X)
" "
"Functions (Aggregate)","BIT_AND"," "Functions (Aggregate)","BIT_AND","
BIT_AND(expression) BIT_AND(expression) [ FILTER ( WHERE expression ) ]
"," ","
The bitwise AND of all non-null values. The bitwise AND of all non-null values.
If no rows are selected, the result is NULL. If no rows are selected, the result is NULL.
...@@ -2657,7 +2657,7 @@ BIT_AND(ID) ...@@ -2657,7 +2657,7 @@ BIT_AND(ID)
" "
"Functions (Aggregate)","BIT_OR"," "Functions (Aggregate)","BIT_OR","
BIT_OR(expression) BIT_OR(expression) [ FILTER ( WHERE expression ) ]
"," ","
The bitwise OR of all non-null values. The bitwise OR of all non-null values.
If no rows are selected, the result is NULL. If no rows are selected, the result is NULL.
...@@ -2667,7 +2667,7 @@ BIT_OR(ID) ...@@ -2667,7 +2667,7 @@ BIT_OR(ID)
" "
"Functions (Aggregate)","BOOL_AND"," "Functions (Aggregate)","BOOL_AND","
BOOL_AND(boolean) BOOL_AND(boolean) [ FILTER ( WHERE expression ) ]
"," ","
Returns true if all expressions are true. Returns true if all expressions are true.
If no rows are selected, the result is NULL. If no rows are selected, the result is NULL.
...@@ -2677,7 +2677,7 @@ BOOL_AND(ID>10) ...@@ -2677,7 +2677,7 @@ BOOL_AND(ID>10)
" "
"Functions (Aggregate)","BOOL_OR"," "Functions (Aggregate)","BOOL_OR","
BOOL_OR(boolean) BOOL_OR(boolean) [ FILTER ( WHERE expression ) ]
"," ","
Returns true if any expression is true. Returns true if any expression is true.
If no rows are selected, the result is NULL. If no rows are selected, the result is NULL.
...@@ -2687,7 +2687,7 @@ BOOL_OR(NAME LIKE 'W%') ...@@ -2687,7 +2687,7 @@ BOOL_OR(NAME LIKE 'W%')
" "
"Functions (Aggregate)","COUNT"," "Functions (Aggregate)","COUNT","
COUNT( { * | { [ DISTINCT ] expression } } ) COUNT( { * | { [ DISTINCT ] expression } } ) [ FILTER ( WHERE expression ) ]
"," ","
The count of all row, or of the non-null values. The count of all row, or of the non-null values.
This method returns a long. This method returns a long.
...@@ -2700,7 +2700,7 @@ COUNT(*) ...@@ -2700,7 +2700,7 @@ COUNT(*)
"Functions (Aggregate)","GROUP_CONCAT"," "Functions (Aggregate)","GROUP_CONCAT","
GROUP_CONCAT ( [ DISTINCT ] string GROUP_CONCAT ( [ DISTINCT ] string
[ ORDER BY { expression [ ASC | DESC ] } [,...] ] [ ORDER BY { expression [ ASC | DESC ] } [,...] ]
[ SEPARATOR expression ] ) [ SEPARATOR expression ] ) [ FILTER ( WHERE expression ) ]
"," ","
Concatenates strings with a separator. Concatenates strings with a separator.
The default separator is a ',' (without space). The default separator is a ',' (without space).
...@@ -2712,7 +2712,7 @@ GROUP_CONCAT(NAME ORDER BY ID SEPARATOR ', ') ...@@ -2712,7 +2712,7 @@ GROUP_CONCAT(NAME ORDER BY ID SEPARATOR ', ')
" "
"Functions (Aggregate)","MAX"," "Functions (Aggregate)","MAX","
MAX(value) MAX(value) [ FILTER ( WHERE expression ) ]
"," ","
The highest value. The highest value.
If no rows are selected, the result is NULL. If no rows are selected, the result is NULL.
...@@ -2723,7 +2723,7 @@ MAX(NAME) ...@@ -2723,7 +2723,7 @@ MAX(NAME)
" "
"Functions (Aggregate)","MIN"," "Functions (Aggregate)","MIN","
MIN(value) MIN(value) [ FILTER ( WHERE expression ) ]
"," ","
The lowest value. The lowest value.
If no rows are selected, the result is NULL. If no rows are selected, the result is NULL.
...@@ -2734,7 +2734,7 @@ MIN(NAME) ...@@ -2734,7 +2734,7 @@ MIN(NAME)
" "
"Functions (Aggregate)","SUM"," "Functions (Aggregate)","SUM","
SUM( [ DISTINCT ] { numeric } ) SUM( [ DISTINCT ] { numeric } ) [ FILTER ( WHERE expression ) ]
"," ","
The sum of all values. The sum of all values.
If no rows are selected, the result is NULL. If no rows are selected, the result is NULL.
...@@ -2746,7 +2746,7 @@ SUM(X) ...@@ -2746,7 +2746,7 @@ SUM(X)
" "
"Functions (Aggregate)","SELECTIVITY"," "Functions (Aggregate)","SELECTIVITY","
SELECTIVITY(value) SELECTIVITY(value) [ FILTER ( WHERE expression ) ]
"," ","
Estimates the selectivity (0-100) of a value. Estimates the selectivity (0-100) of a value.
The value is defined as (100 * distinctCount / rowCount). The value is defined as (100 * distinctCount / rowCount).
...@@ -2758,7 +2758,7 @@ SELECT SELECTIVITY(FIRSTNAME), SELECTIVITY(NAME) FROM TEST WHERE ROWNUM()<20000 ...@@ -2758,7 +2758,7 @@ SELECT SELECTIVITY(FIRSTNAME), SELECTIVITY(NAME) FROM TEST WHERE ROWNUM()<20000
" "
"Functions (Aggregate)","STDDEV_POP"," "Functions (Aggregate)","STDDEV_POP","
STDDEV_POP( [ DISTINCT ] numeric ) STDDEV_POP( [ DISTINCT ] numeric ) [ FILTER ( WHERE expression ) ]
"," ","
The population standard deviation. The population standard deviation.
This method returns a double. This method returns a double.
...@@ -2769,7 +2769,7 @@ STDDEV_POP(X) ...@@ -2769,7 +2769,7 @@ STDDEV_POP(X)
" "
"Functions (Aggregate)","STDDEV_SAMP"," "Functions (Aggregate)","STDDEV_SAMP","
STDDEV_SAMP( [ DISTINCT ] numeric ) STDDEV_SAMP( [ DISTINCT ] numeric ) [ FILTER ( WHERE expression ) ]
"," ","
The sample standard deviation. The sample standard deviation.
This method returns a double. This method returns a double.
...@@ -2780,7 +2780,7 @@ STDDEV(X) ...@@ -2780,7 +2780,7 @@ STDDEV(X)
" "
"Functions (Aggregate)","VAR_POP"," "Functions (Aggregate)","VAR_POP","
VAR_POP( [ DISTINCT ] numeric ) VAR_POP( [ DISTINCT ] numeric ) [ FILTER ( WHERE expression ) ]
"," ","
The population variance (square of the population standard deviation). The population variance (square of the population standard deviation).
This method returns a double. This method returns a double.
...@@ -2791,7 +2791,7 @@ VAR_POP(X) ...@@ -2791,7 +2791,7 @@ VAR_POP(X)
" "
"Functions (Aggregate)","VAR_SAMP"," "Functions (Aggregate)","VAR_SAMP","
VAR_SAMP( [ DISTINCT ] numeric ) VAR_SAMP( [ DISTINCT ] numeric ) [ FILTER ( WHERE expression ) ]
"," ","
The sample variance (square of the sample standard deviation). The sample variance (square of the sample standard deviation).
This method returns a double. This method returns a double.
...@@ -2802,7 +2802,7 @@ VAR_SAMP(X) ...@@ -2802,7 +2802,7 @@ VAR_SAMP(X)
" "
"Functions (Aggregate)","MEDIAN"," "Functions (Aggregate)","MEDIAN","
MEDIAN( [ DISTINCT ] value ) MEDIAN( [ DISTINCT ] value ) [ FILTER ( WHERE expression ) ]
"," ","
The value separating the higher half of a values from the lower half. The value separating the higher half of a values from the lower half.
Returns the middle value or an interpolated value between two middle values if number of values is even. Returns the middle value or an interpolated value between two middle values if number of values is even.
......
...@@ -2627,7 +2627,7 @@ public class Parser { ...@@ -2627,7 +2627,7 @@ public class Parser {
throw getSyntaxError(); throw getSyntaxError();
} }
currentSelect.setGroupQuery(); currentSelect.setGroupQuery();
Expression r; Aggregate r;
if (aggregateType == AggregateType.COUNT) { if (aggregateType == AggregateType.COUNT) {
if (readIf("*")) { if (readIf("*")) {
r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect, r = new Aggregate(AggregateType.COUNT_ALL, null, currentSelect,
...@@ -2645,38 +2645,45 @@ public class Parser { ...@@ -2645,38 +2645,45 @@ public class Parser {
} }
} }
} else if (aggregateType == AggregateType.GROUP_CONCAT) { } else if (aggregateType == AggregateType.GROUP_CONCAT) {
Aggregate agg = null;
boolean distinct = readIf("DISTINCT"); boolean distinct = readIf("DISTINCT");
if (equalsToken("GROUP_CONCAT", aggregateName)) { if (equalsToken("GROUP_CONCAT", aggregateName)) {
agg = new Aggregate(AggregateType.GROUP_CONCAT, r = new Aggregate(AggregateType.GROUP_CONCAT,
readExpression(), currentSelect, distinct); readExpression(), currentSelect, distinct);
if (readIf("ORDER")) { if (readIf("ORDER")) {
read("BY"); read("BY");
agg.setGroupConcatOrder(parseSimpleOrderList()); r.setGroupConcatOrder(parseSimpleOrderList());
} }
if (readIf("SEPARATOR")) { if (readIf("SEPARATOR")) {
agg.setGroupConcatSeparator(readExpression()); r.setGroupConcatSeparator(readExpression());
} }
} else if (equalsToken("STRING_AGG", aggregateName)) { } else if (equalsToken("STRING_AGG", aggregateName)) {
// PostgreSQL compatibility: string_agg(expression, delimiter) // PostgreSQL compatibility: string_agg(expression, delimiter)
agg = new Aggregate(AggregateType.GROUP_CONCAT, r = new Aggregate(AggregateType.GROUP_CONCAT,
readExpression(), currentSelect, distinct); readExpression(), currentSelect, distinct);
read(","); read(",");
agg.setGroupConcatSeparator(readExpression()); r.setGroupConcatSeparator(readExpression());
if (readIf("ORDER")) { if (readIf("ORDER")) {
read("BY"); read("BY");
agg.setGroupConcatOrder(parseSimpleOrderList()); r.setGroupConcatOrder(parseSimpleOrderList());
} }
} else {
r = null;
} }
r = agg;
} else { } else {
boolean distinct = readIf("DISTINCT"); boolean distinct = readIf("DISTINCT");
r = new Aggregate(aggregateType, readExpression(), currentSelect, r = new Aggregate(aggregateType, readExpression(), currentSelect,
distinct); distinct);
} }
read(")"); read(")");
if (r != null && readIf("FILTER")) {
read("(");
read("WHERE");
Expression condition = readExpression();
read(")");
r.setFilterCondition(condition);
}
return r; return r;
} }
...@@ -2727,8 +2734,17 @@ public class Parser { ...@@ -2727,8 +2734,17 @@ public class Parser {
params.add(readExpression()); params.add(readExpression());
} while (readIf(",")); } while (readIf(","));
read(")"); read(")");
Expression filterCondition;
if (readIf("FILTER")) {
read("(");
read("WHERE");
filterCondition = readExpression();
read(")");
} else {
filterCondition = null;
}
Expression[] list = params.toArray(new Expression[0]); Expression[] list = params.toArray(new Expression[0]);
JavaAggregate agg = new JavaAggregate(aggregate, list, currentSelect); JavaAggregate agg = new JavaAggregate(aggregate, list, currentSelect, filterCondition);
currentSelect.setGroupQuery(); currentSelect.setGroupQuery();
return agg; return agg;
} }
......
...@@ -146,6 +146,8 @@ public class Aggregate extends Expression { ...@@ -146,6 +146,8 @@ public class Aggregate extends Expression {
private int displaySize; private int displaySize;
private int lastGroupRowId; private int lastGroupRowId;
private Expression filterCondition;
/** /**
* Create a new aggregate object. * Create a new aggregate object.
* *
...@@ -228,6 +230,15 @@ public class Aggregate extends Expression { ...@@ -228,6 +230,15 @@ public class Aggregate extends Expression {
this.groupConcatSeparator = separator; this.groupConcatSeparator = separator;
} }
/**
* Sets the FILTER condition.
*
* @param filterCondition condition
*/
public void setFilterCondition(Expression filterCondition) {
this.filterCondition = filterCondition;
}
private SortOrder initOrder(Session session) { private SortOrder initOrder(Session session) {
int size = groupConcatOrderList.size(); int size = groupConcatOrderList.size();
int[] index = new int[size]; int[] index = new int[size];
...@@ -281,6 +292,11 @@ public class Aggregate extends Expression { ...@@ -281,6 +292,11 @@ public class Aggregate extends Expression {
} }
} }
} }
if (filterCondition != null) {
if (!filterCondition.getBooleanValue(session)) {
return;
}
}
data.add(session.getDatabase(), dataType, distinct, v); data.add(session.getDatabase(), dataType, distinct, v);
} }
...@@ -383,6 +399,9 @@ public class Aggregate extends Expression { ...@@ -383,6 +399,9 @@ public class Aggregate extends Expression {
if (groupConcatSeparator != null) { if (groupConcatSeparator != null) {
groupConcatSeparator.mapColumns(resolver, level); groupConcatSeparator.mapColumns(resolver, level);
} }
if (filterCondition != null) {
filterCondition.mapColumns(resolver, level);
}
} }
@Override @Override
...@@ -403,6 +422,9 @@ public class Aggregate extends Expression { ...@@ -403,6 +422,9 @@ public class Aggregate extends Expression {
if (groupConcatSeparator != null) { if (groupConcatSeparator != null) {
groupConcatSeparator = groupConcatSeparator.optimize(session); groupConcatSeparator = groupConcatSeparator.optimize(session);
} }
if (filterCondition != null) {
filterCondition = filterCondition.optimize(session);
}
switch (type) { switch (type) {
case GROUP_CONCAT: case GROUP_CONCAT:
dataType = Value.STRING; dataType = Value.STRING;
...@@ -487,6 +509,9 @@ public class Aggregate extends Expression { ...@@ -487,6 +509,9 @@ public class Aggregate extends Expression {
if (groupConcatSeparator != null) { if (groupConcatSeparator != null) {
groupConcatSeparator.setEvaluatable(tableFilter, b); groupConcatSeparator.setEvaluatable(tableFilter, b);
} }
if (filterCondition != null) {
filterCondition.setEvaluatable(tableFilter, b);
}
} }
@Override @Override
...@@ -523,7 +548,11 @@ public class Aggregate extends Expression { ...@@ -523,7 +548,11 @@ public class Aggregate extends Expression {
if (groupConcatSeparator != null) { if (groupConcatSeparator != null) {
buff.append(" SEPARATOR ").append(groupConcatSeparator.getSQL()); buff.append(" SEPARATOR ").append(groupConcatSeparator.getSQL());
} }
return buff.append(')').toString(); buff.append(')');
if (filterCondition != null) {
buff.append(" FILTER (WHERE ").append(filterCondition.getSQL()).append(')');
}
return buff.toString();
} }
@Override @Override
...@@ -586,9 +615,14 @@ public class Aggregate extends Expression { ...@@ -586,9 +615,14 @@ public class Aggregate extends Expression {
throw DbException.throwInternalError("type=" + type); throw DbException.throwInternalError("type=" + type);
} }
if (distinct) { if (distinct) {
return text + "(DISTINCT " + on.getSQL() + ")"; text += "(DISTINCT " + on.getSQL() + ')';
} else {
text += StringUtils.enclose(on.getSQL());
} }
return text + StringUtils.enclose(on.getSQL()); if (filterCondition != null) {
text += " FILTER (WHERE " + filterCondition.getSQL() + ')';
}
return text;
} }
private Index getMinMaxColumnIndex() { private Index getMinMaxColumnIndex() {
...@@ -607,6 +641,9 @@ public class Aggregate extends Expression { ...@@ -607,6 +641,9 @@ public class Aggregate extends Expression {
@Override @Override
public boolean isEverything(ExpressionVisitor visitor) { public boolean isEverything(ExpressionVisitor visitor) {
if (filterCondition != null && !filterCondition.isEverything(visitor)) {
return false;
}
if (visitor.getType() == ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL) { if (visitor.getType() == ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL) {
switch (type) { switch (type) {
case COUNT: case COUNT:
...@@ -649,7 +686,14 @@ public class Aggregate extends Expression { ...@@ -649,7 +686,14 @@ public class Aggregate extends Expression {
@Override @Override
public int getCost() { public int getCost() {
return (on == null) ? 1 : on.getCost() + 1; int cost = 1;
if (on != null) {
cost += on.getCost();
}
if (filterCondition != null) {
cost += filterCondition.getCost();
}
return cost;
} }
} }
...@@ -31,15 +31,17 @@ public class JavaAggregate extends Expression { ...@@ -31,15 +31,17 @@ public class JavaAggregate extends Expression {
private final Select select; private final Select select;
private final Expression[] args; private final Expression[] args;
private int[] argTypes; private int[] argTypes;
private Expression filterCondition;
private int dataType; private int dataType;
private Connection userConnection; private Connection userConnection;
private int lastGroupRowId; private int lastGroupRowId;
public JavaAggregate(UserAggregate userAggregate, Expression[] args, public JavaAggregate(UserAggregate userAggregate, Expression[] args,
Select select) { Select select, Expression filterCondition) {
this.userAggregate = userAggregate; this.userAggregate = userAggregate;
this.args = args; this.args = args;
this.select = select; this.select = select;
this.filterCondition = filterCondition;
} }
@Override @Override
...@@ -48,6 +50,9 @@ public class JavaAggregate extends Expression { ...@@ -48,6 +50,9 @@ public class JavaAggregate extends Expression {
for (Expression e : args) { for (Expression e : args) {
cost += e.getCost(); cost += e.getCost();
} }
if (filterCondition != null) {
cost += filterCondition.getCost();
}
return cost; return cost;
} }
...@@ -74,7 +79,11 @@ public class JavaAggregate extends Expression { ...@@ -74,7 +79,11 @@ public class JavaAggregate extends Expression {
buff.appendExceptFirst(", "); buff.appendExceptFirst(", ");
buff.append(e.getSQL()); buff.append(e.getSQL());
} }
return buff.append(')').toString(); buff.append(')');
if (filterCondition != null) {
buff.append(" FILTER (WHERE ").append(filterCondition.getSQL()).append(')');
}
return buff.toString();
} }
@Override @Override
...@@ -101,6 +110,9 @@ public class JavaAggregate extends Expression { ...@@ -101,6 +110,9 @@ public class JavaAggregate extends Expression {
return false; return false;
} }
} }
if (filterCondition != null && !filterCondition.isEverything(visitor)) {
return false;
}
return true; return true;
} }
...@@ -109,6 +121,9 @@ public class JavaAggregate extends Expression { ...@@ -109,6 +121,9 @@ public class JavaAggregate extends Expression {
for (Expression arg : args) { for (Expression arg : args) {
arg.mapColumns(resolver, level); arg.mapColumns(resolver, level);
} }
if (filterCondition != null) {
filterCondition.mapColumns(resolver, level);
}
} }
@Override @Override
...@@ -128,6 +143,9 @@ public class JavaAggregate extends Expression { ...@@ -128,6 +143,9 @@ public class JavaAggregate extends Expression {
} catch (SQLException e) { } catch (SQLException e) {
throw DbException.convert(e); throw DbException.convert(e);
} }
if (filterCondition != null) {
filterCondition = filterCondition.optimize(session);
}
return this; return this;
} }
...@@ -136,6 +154,9 @@ public class JavaAggregate extends Expression { ...@@ -136,6 +154,9 @@ public class JavaAggregate extends Expression {
for (Expression e : args) { for (Expression e : args) {
e.setEvaluatable(tableFilter, b); e.setEvaluatable(tableFilter, b);
} }
if (filterCondition != null) {
filterCondition.setEvaluatable(tableFilter, b);
}
} }
private Aggregate getInstance() throws SQLException { private Aggregate getInstance() throws SQLException {
...@@ -180,6 +201,12 @@ public class JavaAggregate extends Expression { ...@@ -180,6 +201,12 @@ public class JavaAggregate extends Expression {
} }
lastGroupRowId = groupRowId; lastGroupRowId = groupRowId;
if (filterCondition != null) {
if (!filterCondition.getBooleanValue(session)) {
return;
}
}
Aggregate agg = (Aggregate) group.get(this); Aggregate agg = (Aggregate) group.get(this);
try { try {
if (agg == null) { if (agg == null) {
......
...@@ -747,6 +747,10 @@ public class TestFunctions extends TestBase implements AggregateFunction { ...@@ -747,6 +747,10 @@ public class TestFunctions extends TestBase implements AggregateFunction {
"SELECT SIMPLE_MEDIAN(X) FROM SYSTEM_RANGE(1, 9)"); "SELECT SIMPLE_MEDIAN(X) FROM SYSTEM_RANGE(1, 9)");
rs.next(); rs.next();
assertEquals("5", rs.getString(1)); assertEquals("5", rs.getString(1));
rs = stat.executeQuery(
"SELECT SIMPLE_MEDIAN(X) FILTER (WHERE X > 2) FROM SYSTEM_RANGE(1, 9)");
rs.next();
assertEquals("6", rs.getString(1));
conn.close(); conn.close();
if (config.memory) { if (config.memory) {
......
...@@ -2,3 +2,28 @@ ...@@ -2,3 +2,28 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
-- with filter condition
create table test(v int);
> ok
insert into test values (10), (20), (30), (40), (50), (60), (70), (80), (90), (100), (110), (120);
> update count: 12
select avg(v), avg(v) filter (where v >= 40) from test where v <= 100;
> AVG(V) AVG(V) FILTER (WHERE (V >= 40))
> ------ -------------------------------
> 55 70
> rows: 1
create index test_idx on test(v);
select avg(v), avg(v) filter (where v >= 40) from test where v <= 100;
> AVG(V) AVG(V) FILTER (WHERE (V >= 40))
> ------ -------------------------------
> 55 70
> rows: 1
drop table test;
> ok
...@@ -2,3 +2,31 @@ ...@@ -2,3 +2,31 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
-- with filter condition
create table test(v bigint);
> ok
insert into test values
(0xfffffffffff0), (0xffffffffff0f), (0xfffffffff0ff), (0xffffffff0fff),
(0xfffffff0ffff), (0xffffff0fffff), (0xfffff0ffffff), (0xffff0fffffff),
(0xfff0ffffffff), (0xff0fffffffff), (0xf0ffffffffff), (0x0fffffffffff);
> update count: 12
select bit_and(v), bit_and(v) filter (where v <= 0xffffffff0fff) from test where v >= 0xff0fffffffff;
> BIT_AND(V) BIT_AND(V) FILTER (WHERE (V <= 281474976649215))
> --------------- ------------------------------------------------
> 280375465082880 280375465086975
> rows: 1
create index test_idx on test(v);
select bit_and(v), bit_and(v) filter (where v <= 0xffffffff0fff) from test where v >= 0xff0fffffffff;
> BIT_AND(V) BIT_AND(V) FILTER (WHERE (V <= 281474976649215))
> --------------- ------------------------------------------------
> 280375465082880 280375465086975
> rows: 1
drop table test;
> ok
...@@ -2,3 +2,30 @@ ...@@ -2,3 +2,30 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
-- with filter condition
-- with filter condition
create table test(v bigint);
> ok
insert into test values (1), (2), (4), (8), (16), (32), (64), (128), (256), (512), (1024), (2048);
> update count: 12
select bit_or(v), bit_or(v) filter (where v >= 8) from test where v <= 512;
> BIT_OR(V) BIT_OR(V) FILTER (WHERE (V >= 8))
> --------- ---------------------------------
> 1023 1016
> rows: 1
create index test_idx on test(v);
select bit_or(v), bit_or(v) filter (where v >= 8) from test where v <= 512;
> BIT_OR(V) BIT_OR(V) FILTER (WHERE (V >= 8))
> --------- ---------------------------------
> 1023 1016
> rows: 1
drop table test;
> ok
...@@ -2,3 +2,34 @@ ...@@ -2,3 +2,34 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
-- with filter condition
create table test(v int);
> ok
insert into test values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12);
> update count: 12
select count(v), count(v) filter (where v >= 4) from test where v <= 10;
> COUNT(V) COUNT(V) FILTER (WHERE (V >= 4))
> -------- --------------------------------
> 10 7
> rows: 1
create index test_idx on test(v);
select count(v), count(v) filter (where v >= 4) from test where v <= 10;
> COUNT(V) COUNT(V) FILTER (WHERE (V >= 4))
> -------- --------------------------------
> 10 7
> rows: 1
select count(v), count(v) filter (where v >= 4) from test;
> COUNT(V) COUNT(V) FILTER (WHERE (V >= 4))
> -------- --------------------------------
> 12 9
> rows: 1
drop table test;
> ok
...@@ -2,3 +2,41 @@ ...@@ -2,3 +2,41 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
-- with filter condition
create table test(v varchar);
> ok
insert into test values ('1'), ('2'), ('3'), ('4'), ('5'), ('6'), ('7'), ('8'), ('9');
> update count: 9
select group_concat(v order by v asc separator '-'),
group_concat(v order by v desc separator '-') filter (where v >= '4')
from test where v >= '2';
> GROUP_CONCAT(V ORDER BY V SEPARATOR '-') GROUP_CONCAT(V ORDER BY V DESC SEPARATOR '-') FILTER (WHERE (V >= '4'))
> ---------------------------------------- -----------------------------------------------------------------------
> 2-3-4-5-6-7-8-9 9-8-7-6-5-4
> rows (ordered): 1
create index test_idx on test(v);
select group_concat(v order by v asc separator '-'),
group_concat(v order by v desc separator '-') filter (where v >= '4')
from test where v >= '2';
> GROUP_CONCAT(V ORDER BY V SEPARATOR '-') GROUP_CONCAT(V ORDER BY V DESC SEPARATOR '-') FILTER (WHERE (V >= '4'))
> ---------------------------------------- -----------------------------------------------------------------------
> 2-3-4-5-6-7-8-9 9-8-7-6-5-4
> rows (ordered): 1
select group_concat(v order by v asc separator '-'),
group_concat(v order by v desc separator '-') filter (where v >= '4')
from test;
> GROUP_CONCAT(V ORDER BY V SEPARATOR '-') GROUP_CONCAT(V ORDER BY V DESC SEPARATOR '-') FILTER (WHERE (V >= '4'))
> ---------------------------------------- -----------------------------------------------------------------------
> 1-2-3-4-5-6-7-8-9 9-8-7-6-5-4
> rows (ordered): 1
drop table test;
> ok
...@@ -2,3 +2,34 @@ ...@@ -2,3 +2,34 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
-- with filter condition
create table test(v int);
> ok
insert into test values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12);
> update count: 12
select max(v), max(v) filter (where v <= 8) from test where v <= 10;
> MAX(V) MAX(V) FILTER (WHERE (V <= 8))
> ------ ------------------------------
> 10 8
> rows: 1
create index test_idx on test(v);
select max(v), max(v) filter (where v <= 8) from test where v <= 10;
> MAX(V) MAX(V) FILTER (WHERE (V <= 8))
> ------ ------------------------------
> 10 8
> rows: 1
select max(v), max(v) filter (where v <= 8) from test;
> MAX(V) MAX(V) FILTER (WHERE (V <= 8))
> ------ ------------------------------
> 12 8
> rows: 1
drop table test;
> ok
...@@ -734,3 +734,72 @@ select median(v) from test; ...@@ -734,3 +734,72 @@ select median(v) from test;
drop table test; drop table test;
> ok > ok
-- with filter condition
create table test(v int);
> ok
insert into test values (10), (20), (30), (40), (50), (60), (70), (80), (90), (100), (110), (120);
> update count: 12
select median(v), median(v) filter (where v >= 40) from test where v <= 100;
> MEDIAN(V) MEDIAN(V) FILTER (WHERE (V >= 40))
> --------- ----------------------------------
> 55 70
> rows: 1
create index test_idx on test(v);
select median(v), median(v) filter (where v >= 40) from test where v <= 100;
> MEDIAN(V) MEDIAN(V) FILTER (WHERE (V >= 40))
> --------- ----------------------------------
> 55 70
> rows: 1
select median(v), median(v) filter (where v >= 40) from test;
> MEDIAN(V) MEDIAN(V) FILTER (WHERE (V >= 40))
> --------- ----------------------------------
> 65 80
> rows: 1
drop table test;
> ok
-- with filter and group by
create table test(dept varchar, amount int);
> ok
insert into test values
('First', 10), ('First', 10), ('First', 20), ('First', 30), ('First', 30),
('Second', 5), ('Second', 4), ('Second', 20), ('Second', 22), ('Second', 300),
('Third', 3), ('Third', 100), ('Third', 150), ('Third', 170), ('Third', 400);
select dept, median(amount) from test group by dept order by dept;
> DEPT MEDIAN(AMOUNT)
> ------ --------------
> First 20
> Second 20
> Third 150
> rows (ordered): 3
select dept, median(amount) filter (where amount >= 20) from test group by dept order by dept;
> DEPT MEDIAN(AMOUNT) FILTER (WHERE (AMOUNT >= 20))
> ------ --------------------------------------------
> First 30
> Second 22
> Third 160
> rows (ordered): 3
select dept, median(amount) filter (where amount >= 20) from test
where (amount < 200) group by dept order by dept;
> DEPT MEDIAN(AMOUNT) FILTER (WHERE (AMOUNT >= 20))
> ------ --------------------------------------------
> First 30
> Second 21
> Third 150
> rows (ordered): 3
drop table test;
> ok
...@@ -2,3 +2,34 @@ ...@@ -2,3 +2,34 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
-- with filter condition
create table test(v int);
> ok
insert into test values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12);
> update count: 12
select min(v), min(v) filter (where v >= 4) from test where v >= 2;
> MIN(V) MIN(V) FILTER (WHERE (V >= 4))
> ------ ------------------------------
> 2 4
> rows: 1
create index test_idx on test(v);
select min(v), min(v) filter (where v >= 4) from test where v >= 2;
> MIN(V) MIN(V) FILTER (WHERE (V >= 4))
> ------ ------------------------------
> 2 4
> rows: 1
select min(v), min(v) filter (where v >= 4) from test;
> MIN(V) MIN(V) FILTER (WHERE (V >= 4))
> ------ ------------------------------
> 1 4
> rows: 1
drop table test;
> ok
...@@ -2,3 +2,28 @@ ...@@ -2,3 +2,28 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
-- with filter condition
create table test(v int);
> ok
insert into test values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12);
> update count: 12
select sum(v), sum(v) filter (where v >= 4) from test where v <= 10;
> SUM(V) SUM(V) FILTER (WHERE (V >= 4))
> ------ ------------------------------
> 55 49
> rows: 1
create index test_idx on test(v);
select sum(v), sum(v) filter (where v >= 4) from test where v <= 10;
> SUM(V) SUM(V) FILTER (WHERE (V >= 4))
> ------ ------------------------------
> 55 49
> rows: 1
drop table test;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论