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

Merge pull request #1661 from katzyn/ratio_to_report

Add RATIO_TO_REPORT window function
...@@ -5547,6 +5547,19 @@ SELECT NTH_VALUE(X) IGNORE NULLS OVER ( ...@@ -5547,6 +5547,19 @@ SELECT NTH_VALUE(X) IGNORE NULLS OVER (
), * FROM TEST; ), * FROM TEST;
" "
"Functions (Window)","RATIO_TO_REPORT","
RATIO_TO_REPORT(value)
OVER windowNameOrSpecification
","
Returns the ratio of a value to the sum of all values.
If argument is NULL or sum of all values is 0, then the value of function is NULL.
Window functions are currently experimental in H2 and should be used with caution.
They also may require a lot of memory for large queries.
","
SELECT X, RATIO_TO_REPORT(X) OVER (PARTITION BY CATEGORY), CATEGORY FROM TEST;
"
"System Tables","Information Schema"," "System Tables","Information Schema","
INFORMATION_SCHEMA INFORMATION_SCHEMA
"," ","
......
...@@ -48,6 +48,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -48,6 +48,7 @@ public class WindowFunction extends DataAnalysisOperation {
case LAG: case LAG:
case FIRST_VALUE: case FIRST_VALUE:
case LAST_VALUE: case LAST_VALUE:
case RATIO_TO_REPORT:
return 1; return 1;
case NTH_VALUE: case NTH_VALUE:
return 2; return 2;
...@@ -68,6 +69,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -68,6 +69,7 @@ public class WindowFunction extends DataAnalysisOperation {
case NTILE: case NTILE:
case FIRST_VALUE: case FIRST_VALUE:
case LAST_VALUE: case LAST_VALUE:
case RATIO_TO_REPORT:
return 1; return 1;
case LEAD: case LEAD:
case LAG: case LAG:
...@@ -207,6 +209,9 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -207,6 +209,9 @@ public class WindowFunction extends DataAnalysisOperation {
case NTH_VALUE: case NTH_VALUE:
getNth(session, result, ordered, rowIdColumn); getNth(session, result, ordered, rowIdColumn);
break; break;
case RATIO_TO_REPORT:
getRatioToReport(session, result, ordered, rowIdColumn);
break;
default: default:
throw DbException.throwInternalError("type=" + type); throw DbException.throwInternalError("type=" + type);
} }
...@@ -375,6 +380,38 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -375,6 +380,38 @@ public class WindowFunction extends DataAnalysisOperation {
} }
} }
private static void getRatioToReport(Session session, HashMap<Integer, Value> result, ArrayList<Value[]> ordered,
int rowIdColumn) {
int size = ordered.size();
Value value = null;
for (int i = 0; i < size; i++) {
Value v = ordered.get(i)[0];
if (v != ValueNull.INSTANCE) {
if (value == null) {
value = v.convertTo(Value.DOUBLE);
} else {
value = value.add(v.convertTo(Value.DOUBLE));
}
}
}
if (value != null && value.getSignum() == 0) {
value = null;
}
for (int i = 0; i < size; i++) {
Value[] row = ordered.get(i);
Value v;
if (value == null) {
v = ValueNull.INSTANCE;
} else {
v = row[0];
if (v != ValueNull.INSTANCE) {
v = v.convertTo(Value.DOUBLE).divide(value);
}
}
result.put(row[rowIdColumn].getInt(), v);
}
}
@Override @Override
protected Value getAggregatedValue(Session session, Object aggregateData) { protected Value getAggregatedValue(Session session, Object aggregateData) {
throw DbException.getUnsupportedException("Window function"); throw DbException.getUnsupportedException("Window function");
...@@ -444,6 +481,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -444,6 +481,7 @@ public class WindowFunction extends DataAnalysisOperation {
return Value.LONG; return Value.LONG;
case PERCENT_RANK: case PERCENT_RANK:
case CUME_DIST: case CUME_DIST:
case RATIO_TO_REPORT:
return Value.DOUBLE; return Value.DOUBLE;
case LEAD: case LEAD:
case LAG: case LAG:
...@@ -480,6 +518,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -480,6 +518,7 @@ public class WindowFunction extends DataAnalysisOperation {
return ValueLong.PRECISION; return ValueLong.PRECISION;
case PERCENT_RANK: case PERCENT_RANK:
case CUME_DIST: case CUME_DIST:
case RATIO_TO_REPORT:
return ValueDouble.PRECISION; return ValueDouble.PRECISION;
case LEAD: case LEAD:
case LAG: case LAG:
...@@ -502,6 +541,7 @@ public class WindowFunction extends DataAnalysisOperation { ...@@ -502,6 +541,7 @@ public class WindowFunction extends DataAnalysisOperation {
return ValueLong.DISPLAY_SIZE; return ValueLong.DISPLAY_SIZE;
case PERCENT_RANK: case PERCENT_RANK:
case CUME_DIST: case CUME_DIST:
case RATIO_TO_REPORT:
return ValueDouble.DISPLAY_SIZE; return ValueDouble.DISPLAY_SIZE;
case LEAD: case LEAD:
case LAG: case LAG:
......
...@@ -65,6 +65,11 @@ public enum WindowFunctionType { ...@@ -65,6 +65,11 @@ public enum WindowFunctionType {
*/ */
NTH_VALUE, NTH_VALUE,
/**
* The type for RATIO_TO_REPORT() window function.
*/
RATIO_TO_REPORT,
; ;
/** /**
...@@ -98,6 +103,8 @@ public enum WindowFunctionType { ...@@ -98,6 +103,8 @@ public enum WindowFunctionType {
return LAST_VALUE; return LAST_VALUE;
case "NTH_VALUE": case "NTH_VALUE":
return NTH_VALUE; return NTH_VALUE;
case "RATIO_TO_REPORT":
return RATIO_TO_REPORT;
default: default:
return null; return null;
} }
......
...@@ -204,7 +204,7 @@ public class TestScript extends TestDb { ...@@ -204,7 +204,7 @@ public class TestScript extends TestDb {
"parsedatetime", "quarter", "second", "truncate", "week", "year", "date_trunc" }) { "parsedatetime", "quarter", "second", "truncate", "week", "year", "date_trunc" }) {
testScript("functions/timeanddate/" + s + ".sql"); testScript("functions/timeanddate/" + s + ".sql");
} }
for (String s : new String[] { "lead", "nth_value", "ntile", "row_number" }) { for (String s : new String[] { "lead", "nth_value", "ntile", "ratio_to_report", "row_number" }) {
testScript("functions/window/" + s + ".sql"); testScript("functions/window/" + s + ".sql");
} }
......
-- Copyright 2004-2019 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(ID INT PRIMARY KEY, N NUMERIC);
> ok
INSERT INTO TEST VALUES(1, 1), (2, 2), (3, NULL), (4, 5);
> update count: 4
SELECT ID, N, RATIO_TO_REPORT(N) OVER() R2R FROM TEST;
> ID N R2R
> -- ---- -----
> 1 1 0.125
> 2 2 0.25
> 3 null null
> 4 5 0.625
> rows: 4
INSERT INTO TEST VALUES (5, -8);
> update count: 1
SELECT ID, N, RATIO_TO_REPORT(N) OVER() R2R FROM TEST;
> ID N R2R
> -- ---- ----
> 1 1 null
> 2 2 null
> 3 null null
> 4 5 null
> 5 -8 null
> rows: 5
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论