Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
4f23bb18
Unverified
提交
4f23bb18
authored
6 年前
作者:
Evgenij Ryazanov
提交者:
GitHub
6 年前
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1456 from katzyn/window
Add experimental implementation of remaining types of window frames
上级
a1314402
1b33a3de
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
746 行增加
和
173 行删除
+746
-173
help.csv
h2/src/docsrc/help/help.csv
+26
-5
Parser.java
h2/src/main/org/h2/command/Parser.java
+84
-40
AbstractAggregate.java
...c/main/org/h2/expression/aggregate/AbstractAggregate.java
+1
-1
Window.java
h2/src/main/org/h2/expression/aggregate/Window.java
+5
-0
WindowFrame.java
h2/src/main/org/h2/expression/aggregate/WindowFrame.java
+253
-122
WindowFrameBound.java
...rc/main/org/h2/expression/aggregate/WindowFrameBound.java
+70
-0
WindowFrameBoundType.java
...ain/org/h2/expression/aggregate/WindowFrameBoundType.java
+54
-0
WindowFrameExclusion.java
...ain/org/h2/expression/aggregate/WindowFrameExclusion.java
+51
-0
WindowFrameUnits.java
...rc/main/org/h2/expression/aggregate/WindowFrameUnits.java
+40
-0
WindowFunction.java
h2/src/main/org/h2/expression/aggregate/WindowFunction.java
+3
-3
array-agg.sql
...est/org/h2/test/scripts/functions/aggregate/array-agg.sql
+157
-0
nth_value.sql
...c/test/org/h2/test/scripts/functions/window/nth_value.sql
+2
-2
没有找到文件。
h2/src/docsrc/help/help.csv
浏览文件 @
4f23bb18
...
...
@@ -2550,11 +2550,8 @@ They also may require a lot of memory for large queries.
"
"Other Grammar","Window frame","
[RANGE BETWEEN {
UNBOUNDED PRECEDING AND CURRENT ROW
|CURRENT ROW AND UNBOUNDED FOLLOWING
|UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
}]
ROWS|RANGE|GROUP
{windowFramePreceding|BETWEEN windowFrameBound AND windowFrameBound}
[EXCLUDE {CURRENT ROW|GROUP|TIES|NO OTHERS}]
","
A window frame clause.
...
...
@@ -2563,6 +2560,30 @@ Is currently supported only in aggregates and FIRST_VALUE(), LAST_VALUE(), and N
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE GROUP
"
"Other Grammar","Window frame preceding","
UNBOUNDED PRECEDING|value PRECEDING|CURRENT ROW
","
A window frame preceding clause.
If value is specified it should be non-negative value or parameter.
","
UNBOUNDED PRECEDING
1 PRECEDING
CURRENT ROW
"
"Other Grammar","Window frame bound","
UNBOUNDED PRECEDING|value PRECEDING|CURRENT ROW
|value FOLLOWING|UNBOUNDED FOLLOWING
","
A window frame bound clause.
If value is specified it should be non-negative value or parameter.
","
UNBOUNDED PRECEDING
UNBOUNDED FOLLOWING
1 FOLLOWING
CURRENT ROW
"
"Other Grammar","Term","
value
| columnName
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/Parser.java
浏览文件 @
4f23bb18
...
...
@@ -176,8 +176,10 @@ import org.h2.expression.aggregate.Aggregate.AggregateType;
import
org.h2.expression.aggregate.JavaAggregate
;
import
org.h2.expression.aggregate.Window
;
import
org.h2.expression.aggregate.WindowFrame
;
import
org.h2.expression.aggregate.WindowFrame.SimpleExtent
;
import
org.h2.expression.aggregate.WindowFrame.WindowFrameExclusion
;
import
org.h2.expression.aggregate.WindowFrameBound
;
import
org.h2.expression.aggregate.WindowFrameBoundType
;
import
org.h2.expression.aggregate.WindowFrameExclusion
;
import
org.h2.expression.aggregate.WindowFrameUnits
;
import
org.h2.expression.aggregate.WindowFunction
;
import
org.h2.expression.aggregate.WindowFunction.WindowFunctionType
;
import
org.h2.index.Index
;
...
...
@@ -3074,8 +3076,7 @@ public class Parser {
frame
=
readWindowFrame
();
break
;
default
:
frame
=
new
WindowFrame
(
SimpleExtent
.
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_CURRENT_ROW
,
WindowFrameExclusion
.
EXCLUDE_NO_OTHERS
);
frame
=
null
;
}
}
else
{
frame
=
readWindowFrame
();
...
...
@@ -3092,46 +3093,89 @@ public class Parser {
}
private
WindowFrame
readWindowFrame
()
{
SimpleExtent
extent
;
WindowFrameUnits
units
;
if
(
readIf
(
"ROWS"
))
{
units
=
WindowFrameUnits
.
ROWS
;
}
else
if
(
readIf
(
"RANGE"
))
{
units
=
WindowFrameUnits
.
RANGE
;
}
else
if
(
readIf
(
"GROUPS"
))
{
units
=
WindowFrameUnits
.
GROUPS
;
}
else
{
return
null
;
}
WindowFrameBound
starting
,
following
;
if
(
readIf
(
"BETWEEN"
))
{
starting
=
readWindowFrameRange
();
read
(
"AND"
);
following
=
readWindowFrameRange
();
}
else
{
starting
=
readWindowFrameStarting
();
following
=
null
;
}
int
idx
=
lastParseIndex
;
WindowFrameExclusion
exclusion
=
WindowFrameExclusion
.
EXCLUDE_NO_OTHERS
;
if
(
readIf
(
"RANGE"
))
{
read
(
"BETWEEN"
);
if
(
readIf
(
"UNBOUNDED"
))
{
read
(
"PRECEDING"
);
read
(
"AND"
);
if
(
readIf
(
"CURRENT"
))
{
read
(
"ROW"
);
extent
=
SimpleExtent
.
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_CURRENT_ROW
;
}
else
{
read
(
"UNBOUNDED"
);
read
(
"FOLLOWING"
);
extent
=
SimpleExtent
.
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_UNBOUNDED_FOLLOWING
;
}
}
else
{
read
(
"CURRENT"
);
if
(
readIf
(
"EXCLUDE"
))
{
if
(
readIf
(
"CURRENT"
))
{
read
(
"ROW"
);
read
(
"AND"
);
read
(
"UNBOUNDED"
);
read
(
"FOLLOWING"
);
extent
=
SimpleExtent
.
RANGE_BETWEEN_CURRENT_ROW_AND_UNBOUNDED_FOLLOWING
;
}
if
(
readIf
(
"EXCLUDE"
))
{
if
(
readIf
(
"CURRENT"
))
{
read
(
"ROW"
);
exclusion
=
WindowFrameExclusion
.
EXCLUDE_CURRENT_ROW
;
}
else
if
(
readIf
(
GROUP
))
{
exclusion
=
WindowFrameExclusion
.
EXCLUDE_GROUP
;
}
else
if
(
readIf
(
"TIES"
))
{
exclusion
=
WindowFrameExclusion
.
EXCLUDE_TIES
;
}
else
{
read
(
"NO"
);
read
(
"OTHERS"
);
}
exclusion
=
WindowFrameExclusion
.
EXCLUDE_CURRENT_ROW
;
}
else
if
(
readIf
(
GROUP
))
{
exclusion
=
WindowFrameExclusion
.
EXCLUDE_GROUP
;
}
else
if
(
readIf
(
"TIES"
))
{
exclusion
=
WindowFrameExclusion
.
EXCLUDE_TIES
;
}
else
{
read
(
"NO"
);
read
(
"OTHERS"
);
}
}
else
{
extent
=
SimpleExtent
.
RANGE_BETWEEN_UNBOUNDED_PRECEDING_AND_CURRENT_ROW
;
}
return
new
WindowFrame
(
extent
,
exclusion
);
WindowFrame
frame
=
new
WindowFrame
(
units
,
starting
,
following
,
exclusion
);
if
(!
frame
.
isValid
())
{
throw
DbException
.
getSyntaxError
(
sqlCommand
,
idx
);
}
return
frame
;
}
private
WindowFrameBound
readWindowFrameStarting
()
{
if
(
readIf
(
"UNBOUNDED"
))
{
read
(
"PRECEDING"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
UNBOUNDED_PRECEDING
,
null
);
}
if
(
readIf
(
"CURRENT"
))
{
read
(
"ROW"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
CURRENT_ROW
,
null
);
}
Expression
value
=
readValueOrParameter
();
read
(
"PRECEDING"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
PRECEDING
,
value
);
}
private
WindowFrameBound
readWindowFrameRange
()
{
if
(
readIf
(
"UNBOUNDED"
))
{
if
(
readIf
(
"PRECEDING"
))
{
return
new
WindowFrameBound
(
WindowFrameBoundType
.
UNBOUNDED_PRECEDING
,
null
);
}
read
(
"FOLLOWING"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
UNBOUNDED_FOLLOWING
,
null
);
}
if
(
readIf
(
"CURRENT"
))
{
read
(
"ROW"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
CURRENT_ROW
,
null
);
}
Expression
value
=
readValueOrParameter
();
if
(
readIf
(
"PRECEDING"
))
{
return
new
WindowFrameBound
(
WindowFrameBoundType
.
PRECEDING
,
value
);
}
read
(
"FOLLOWING"
);
return
new
WindowFrameBound
(
WindowFrameBoundType
.
FOLLOWING
,
value
);
}
private
Expression
readValueOrParameter
()
{
int
index
=
parseIndex
;
Expression
value
=
readExpression
();
if
(!(
value
instanceof
ValueExpression
)
&&
!(
value
instanceof
Parameter
))
{
parseIndex
=
index
;
throw
getSyntaxError
();
}
return
value
;
}
private
AggregateType
getAggregateType
(
String
name
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/AbstractAggregate.java
浏览文件 @
4f23bb18
...
...
@@ -445,7 +445,7 @@ public abstract class AbstractAggregate extends Expression {
int
size
=
ordered
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
Object
aggregateData
=
createAggregateData
();
for
(
Iterator
<
Value
[]>
iter
=
frame
.
iterator
(
ordered
,
getOverOrderBySort
(),
i
,
false
);
iter
for
(
Iterator
<
Value
[]>
iter
=
frame
.
iterator
(
session
,
ordered
,
getOverOrderBySort
(),
i
,
false
);
iter
.
hasNext
();)
{
updateFromExpressions
(
session
,
aggregateData
,
iter
.
next
());
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/Window.java
浏览文件 @
4f23bb18
...
...
@@ -64,6 +64,11 @@ public final class Window {
public
Window
(
ArrayList
<
Expression
>
partitionBy
,
ArrayList
<
SelectOrderBy
>
orderBy
,
WindowFrame
frame
)
{
this
.
partitionBy
=
partitionBy
;
this
.
orderBy
=
orderBy
;
if
(
frame
==
null
)
{
frame
=
new
WindowFrame
(
WindowFrameUnits
.
RANGE
,
new
WindowFrameBound
(
WindowFrameBoundType
.
UNBOUNDED_PRECEDING
,
null
),
null
,
WindowFrameExclusion
.
EXCLUDE_NO_OTHERS
);
}
this
.
frame
=
frame
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/WindowFrame.java
浏览文件 @
4f23bb18
差异被折叠。
点击展开。
h2/src/main/org/h2/expression/aggregate/WindowFrameBound.java
0 → 100644
浏览文件 @
4f23bb18
/*
* 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
org.h2.expression.Expression
;
/**
* Window frame bound.
*/
public
class
WindowFrameBound
{
private
final
WindowFrameBoundType
type
;
private
final
Expression
value
;
/**
* Creates new instance of window frame bound.
*
* @param type
* bound type
* @param value
* bound value, if any
*/
public
WindowFrameBound
(
WindowFrameBoundType
type
,
Expression
value
)
{
this
.
type
=
type
;
if
(
type
==
WindowFrameBoundType
.
PRECEDING
||
type
==
WindowFrameBoundType
.
FOLLOWING
)
{
this
.
value
=
value
;
}
else
{
this
.
value
=
null
;
}
}
/**
* Returns the type
*
* @return the type
*/
public
WindowFrameBoundType
getType
()
{
return
type
;
}
/**
* Returns the value.
*
* @return the value
*/
public
Expression
getValue
()
{
return
value
;
}
/**
* Returns SQL representation.
*
* @param following
* if false return SQL for starting clause, if true return SQL
* for following clause
* @return SQL representation.
* @see Expression#getSQL()
*/
public
String
getSQL
(
boolean
following
)
{
if
(
type
==
WindowFrameBoundType
.
PRECEDING
||
type
==
WindowFrameBoundType
.
FOLLOWING
)
{
return
value
.
getSQL
()
+
' '
+
type
.
getSQL
();
}
return
type
.
getSQL
();
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/WindowFrameBoundType.java
0 → 100644
浏览文件 @
4f23bb18
/*
* 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
;
/**
* Window frame bound type.
*/
public
enum
WindowFrameBoundType
{
/**
* UNBOUNDED PRECEDING clause.
*/
UNBOUNDED_PRECEDING
(
"UNBOUNDED PRECEDING"
),
/**
* PRECEDING clause.
*/
PRECEDING
(
"PRECEDING"
),
/**
* CURRENT_ROW clause.
*/
CURRENT_ROW
(
"CURRENT_ROW"
),
/**
* FOLLOWING clause.
*/
FOLLOWING
(
"FOLLOWING"
),
/**
* UNBOUNDED FOLLOWING clause.
*/
UNBOUNDED_FOLLOWING
(
"UNBOUNDED FOLLOWING"
);
private
final
String
sql
;
private
WindowFrameBoundType
(
String
sql
)
{
this
.
sql
=
sql
;
}
/**
* Returns SQL representation.
*
* @return SQL representation.
* @see org.h2.expression.Expression#getSQL()
*/
public
String
getSQL
()
{
return
sql
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/WindowFrameExclusion.java
0 → 100644
浏览文件 @
4f23bb18
/*
* 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
;
/**
* Window frame exclusion clause.
*/
public
enum
WindowFrameExclusion
{
/**
* EXCLUDE CURRENT ROW exclusion clause.
*/
EXCLUDE_CURRENT_ROW
(
"EXCLUDE CURRENT ROW"
),
/**
* EXCLUDE GROUP exclusion clause.
*/
EXCLUDE_GROUP
(
"EXCLUDE GROUP"
),
/**
* EXCLUDE TIES exclusion clause.
*/
EXCLUDE_TIES
(
"EXCLUDE TIES"
),
/**
* EXCLUDE NO OTHERS exclusion clause.
*/
EXCLUDE_NO_OTHERS
(
"EXCLUDE NO OTHERS"
),
;
private
final
String
sql
;
private
WindowFrameExclusion
(
String
sql
)
{
this
.
sql
=
sql
;
}
/**
* Returns SQL representation.
*
* @return SQL representation.
* @see org.h2.expression.Expression#getSQL()
*/
public
String
getSQL
()
{
return
sql
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/WindowFrameUnits.java
0 → 100644
浏览文件 @
4f23bb18
/*
* 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
;
/**
* Window frame units.
*/
public
enum
WindowFrameUnits
{
/**
* ROWS unit.
*/
ROWS
,
/**
* RANGE unit.
*/
RANGE
,
/**
* GROUPS unit.
*/
GROUPS
,
;
/**
* Returns SQL representation.
*
* @return SQL representation.
* @see org.h2.expression.Expression#getSQL()
*/
public
String
getSQL
()
{
return
name
();
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/aggregate/WindowFunction.java
浏览文件 @
4f23bb18
...
...
@@ -321,11 +321,11 @@ public class WindowFunction extends AbstractAggregate {
Value
v
;
switch
(
type
)
{
case
FIRST_VALUE:
{
v
=
getNthValue
(
frame
.
iterator
(
ordered
,
getOverOrderBySort
(),
i
,
false
),
0
,
ignoreNulls
);
v
=
getNthValue
(
frame
.
iterator
(
session
,
ordered
,
getOverOrderBySort
(),
i
,
false
),
0
,
ignoreNulls
);
break
;
}
case
LAST_VALUE:
v
=
getNthValue
(
frame
.
iterator
(
ordered
,
getOverOrderBySort
(),
i
,
true
),
0
,
ignoreNulls
);
v
=
getNthValue
(
frame
.
iterator
(
session
,
ordered
,
getOverOrderBySort
(),
i
,
true
),
0
,
ignoreNulls
);
break
;
case
NTH_VALUE:
{
int
n
=
row
[
1
].
getInt
();
...
...
@@ -333,7 +333,7 @@ public class WindowFunction extends AbstractAggregate {
throw
DbException
.
getInvalidValueException
(
"nth row"
,
n
);
}
n
--;
Iterator
<
Value
[]>
iter
=
frame
.
iterator
(
ordered
,
getOverOrderBySort
(),
i
,
fromLast
);
Iterator
<
Value
[]>
iter
=
frame
.
iterator
(
session
,
ordered
,
getOverOrderBySort
(),
i
,
fromLast
);
v
=
getNthValue
(
iter
,
n
,
ignoreNulls
);
break
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/aggregate/array-agg.sql
浏览文件 @
4f23bb18
...
...
@@ -275,3 +275,160 @@ SELECT
DROP
TABLE
TEST
;
>
ok
CREATE
TABLE
TEST
(
ID
INT
,
VALUE
INT
);
>
ok
INSERT
INTO
TEST
VALUES
(
1
,
1
),
(
2
,
1
),
(
3
,
5
),
(
4
,
8
),
(
5
,
8
),
(
6
,
8
),
(
7
,
9
),
(
8
,
9
);
>
update
count
:
8
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
ROWS
BETWEEN
1
PRECEDING
AND
1
FOLLOWING
)
R_ID
,
ARRAY_AGG
(
VALUE
)
OVER
(
ORDER
BY
VALUE
ROWS
BETWEEN
1
PRECEDING
AND
1
FOLLOWING
)
R_V
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
RANGE
BETWEEN
1
PRECEDING
AND
1
FOLLOWING
)
V_ID
,
ARRAY_AGG
(
VALUE
)
OVER
(
ORDER
BY
VALUE
RANGE
BETWEEN
1
PRECEDING
AND
1
FOLLOWING
)
V_V
,
ARRAY_AGG
(
VALUE
)
OVER
(
ORDER
BY
VALUE
DESC
RANGE
BETWEEN
1
PRECEDING
AND
1
FOLLOWING
)
V_V_R
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
GROUPS
BETWEEN
1
PRECEDING
AND
1
FOLLOWING
)
G_ID
,
ARRAY_AGG
(
VALUE
)
OVER
(
ORDER
BY
VALUE
GROUPS
BETWEEN
1
PRECEDING
AND
1
FOLLOWING
)
G_V
FROM
TEST
;
>
ID
VALUE
R_ID
R_V
V_ID
V_V
V_V_R
G_ID
G_V
>
-- ----- --------- --------- --------------- --------------- --------------- ------------------ ------------------
>
1
1
(
1
,
2
)
(
1
,
1
)
(
1
,
2
)
(
1
,
1
)
(
1
,
1
)
(
1
,
2
,
3
)
(
1
,
1
,
5
)
>
2
1
(
1
,
2
,
3
)
(
1
,
1
,
5
)
(
1
,
2
)
(
1
,
1
)
(
1
,
1
)
(
1
,
2
,
3
)
(
1
,
1
,
5
)
>
3
5
(
2
,
3
,
4
)
(
1
,
5
,
8
)
(
3
)
(
5
)
(
5
)
(
1
,
2
,
3
,
4
,
5
,
6
)
(
1
,
1
,
5
,
8
,
8
,
8
)
>
4
8
(
3
,
4
,
5
)
(
5
,
8
,
8
)
(
4
,
5
,
6
,
7
,
8
)
(
8
,
8
,
8
,
9
,
9
)
(
9
,
9
,
8
,
8
,
8
)
(
3
,
4
,
5
,
6
,
7
,
8
)
(
5
,
8
,
8
,
8
,
9
,
9
)
>
5
8
(
4
,
5
,
6
)
(
8
,
8
,
8
)
(
4
,
5
,
6
,
7
,
8
)
(
8
,
8
,
8
,
9
,
9
)
(
9
,
9
,
8
,
8
,
8
)
(
3
,
4
,
5
,
6
,
7
,
8
)
(
5
,
8
,
8
,
8
,
9
,
9
)
>
6
8
(
5
,
6
,
7
)
(
8
,
8
,
9
)
(
4
,
5
,
6
,
7
,
8
)
(
8
,
8
,
8
,
9
,
9
)
(
9
,
9
,
8
,
8
,
8
)
(
3
,
4
,
5
,
6
,
7
,
8
)
(
5
,
8
,
8
,
8
,
9
,
9
)
>
7
9
(
6
,
7
,
8
)
(
8
,
9
,
9
)
(
4
,
5
,
6
,
7
,
8
)
(
8
,
8
,
8
,
9
,
9
)
(
9
,
9
,
8
,
8
,
8
)
(
4
,
5
,
6
,
7
,
8
)
(
8
,
8
,
8
,
9
,
9
)
>
8
9
(
7
,
8
)
(
9
,
9
)
(
4
,
5
,
6
,
7
,
8
)
(
8
,
8
,
8
,
9
,
9
)
(
9
,
9
,
8
,
8
,
8
)
(
4
,
5
,
6
,
7
,
8
)
(
8
,
8
,
8
,
9
,
9
)
>
rows
(
ordered
):
8
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
ROWS
-
1
PRECEDING
)
FROM
TEST
;
>
exception
INVALID_VALUE_2
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
ID
ROWS
BETWEEN
2
PRECEDING
AND
1
PRECEDING
)
FROM
TEST
FETCH
FIRST
4
ROWS
ONLY
;
>
ID
VALUE
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
ID
ROWS
BETWEEN
2
PRECEDING
AND
1
PRECEDING
)
>
-- ----- -------------------------------------------------------------------------
>
1
1
null
>
2
1
(
1
)
>
3
5
(
1
,
2
)
>
4
8
(
2
,
3
)
>
rows
(
ordered
):
4
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
ID
ROWS
BETWEEN
1
FOLLOWING
AND
2
FOLLOWING
)
FROM
TEST
OFFSET
4
ROWS
;
>
ID
VALUE
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
ID
ROWS
BETWEEN
1
FOLLOWING
AND
2
FOLLOWING
)
>
-- ----- -------------------------------------------------------------------------
>
5
8
(
6
,
7
)
>
6
8
(
7
,
8
)
>
7
9
(
8
)
>
8
9
null
>
rows
(
ordered
):
4
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
ID
RANGE
BETWEEN
2
PRECEDING
AND
1
PRECEDING
)
FROM
TEST
FETCH
FIRST
4
ROWS
ONLY
;
>
ID
VALUE
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
ID
RANGE
BETWEEN
2
PRECEDING
AND
1
PRECEDING
)
>
-- ----- --------------------------------------------------------------------------
>
1
1
null
>
2
1
(
1
)
>
3
5
(
1
,
2
)
>
4
8
(
2
,
3
)
>
rows
(
ordered
):
4
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
ID
RANGE
BETWEEN
1
FOLLOWING
AND
2
FOLLOWING
)
FROM
TEST
OFFSET
4
ROWS
;
>
ID
VALUE
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
ID
RANGE
BETWEEN
1
FOLLOWING
AND
2
FOLLOWING
)
>
-- ----- --------------------------------------------------------------------------
>
5
8
(
6
,
7
)
>
6
8
(
7
,
8
)
>
7
9
(
8
)
>
8
9
null
>
rows
(
ordered
):
4
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
1
PRECEDING
)
U_P
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
GROUPS
BETWEEN
2
PRECEDING
AND
1
PRECEDING
)
P
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
GROUPS
BETWEEN
1
FOLLOWING
AND
2
FOLLOWING
)
F
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
GROUPS
BETWEEN
1
FOLLOWING
AND
UNBOUNDED
FOLLOWING
)
U_F
FROM
TEST
;
>
ID
VALUE
U_P
P
F
U_F
>
-- ----- ------------------ ------------ --------------- ------------------
>
1
1
null
null
(
3
,
4
,
5
,
6
)
(
3
,
4
,
5
,
6
,
7
,
8
)
>
2
1
null
null
(
3
,
4
,
5
,
6
)
(
3
,
4
,
5
,
6
,
7
,
8
)
>
3
5
(
1
,
2
)
(
1
,
2
)
(
4
,
5
,
6
,
7
,
8
)
(
4
,
5
,
6
,
7
,
8
)
>
4
8
(
1
,
2
,
3
)
(
1
,
2
,
3
)
(
7
,
8
)
(
7
,
8
)
>
5
8
(
1
,
2
,
3
)
(
1
,
2
,
3
)
(
7
,
8
)
(
7
,
8
)
>
6
8
(
1
,
2
,
3
)
(
1
,
2
,
3
)
(
7
,
8
)
(
7
,
8
)
>
7
9
(
1
,
2
,
3
,
4
,
5
,
6
)
(
3
,
4
,
5
,
6
)
null
null
>
8
9
(
1
,
2
,
3
,
4
,
5
,
6
)
(
3
,
4
,
5
,
6
)
null
null
>
rows
(
ordered
):
8
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
GROUPS
BETWEEN
1
PRECEDING
AND
0
PRECEDING
)
P
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
GROUPS
BETWEEN
0
FOLLOWING
AND
1
FOLLOWING
)
F
FROM
TEST
;
>
ID
VALUE
P
F
>
-- ----- --------------- ---------------
>
1
1
(
1
,
2
)
(
1
,
2
,
3
)
>
2
1
(
1
,
2
)
(
1
,
2
,
3
)
>
3
5
(
1
,
2
,
3
)
(
3
,
4
,
5
,
6
)
>
4
8
(
3
,
4
,
5
,
6
)
(
4
,
5
,
6
,
7
,
8
)
>
5
8
(
3
,
4
,
5
,
6
)
(
4
,
5
,
6
,
7
,
8
)
>
6
8
(
3
,
4
,
5
,
6
)
(
4
,
5
,
6
,
7
,
8
)
>
7
9
(
4
,
5
,
6
,
7
,
8
)
(
7
,
8
)
>
8
9
(
4
,
5
,
6
,
7
,
8
)
(
7
,
8
)
>
rows
(
ordered
):
8
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
ID
RANGE
BETWEEN
CURRENT
ROW
AND
1
PRECEDING
)
FROM
TEST
;
>
exception
SYNTAX_ERROR_1
DROP
TABLE
TEST
;
>
ok
CREATE
TABLE
TEST
(
ID
INT
,
VALUE
INT
);
>
ok
INSERT
INTO
TEST
VALUES
(
1
,
1
),
(
2
,
1
),
(
3
,
2
),
(
4
,
2
),
(
5
,
3
),
(
6
,
3
),
(
7
,
4
),
(
8
,
4
);
>
update
count
:
8
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
RANGE
BETWEEN
2
PRECEDING
AND
1
PRECEDING
)
FROM
TEST
;
>
ID
VALUE
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
RANGE
BETWEEN
2
PRECEDING
AND
1
PRECEDING
)
>
-- ----- -----------------------------------------------------------------------------
>
1
1
null
>
2
1
null
>
3
2
(
1
,
2
)
>
4
2
(
1
,
2
)
>
5
3
(
1
,
2
,
3
,
4
)
>
6
3
(
1
,
2
,
3
,
4
)
>
7
4
(
3
,
4
,
5
,
6
)
>
8
4
(
3
,
4
,
5
,
6
)
>
rows
(
ordered
):
8
SELECT
*
,
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
RANGE
BETWEEN
1
FOLLOWING
AND
2
FOLLOWING
)
FROM
TEST
;
>
ID
VALUE
ARRAY_AGG
(
ID
)
OVER
(
ORDER
BY
VALUE
RANGE
BETWEEN
1
FOLLOWING
AND
2
FOLLOWING
)
>
-- ----- -----------------------------------------------------------------------------
>
1
1
(
3
,
4
,
5
,
6
)
>
2
1
(
3
,
4
,
5
,
6
)
>
3
2
(
5
,
6
,
7
,
8
)
>
4
2
(
5
,
6
,
7
,
8
)
>
5
3
(
7
,
8
)
>
6
3
(
7
,
8
)
>
7
4
null
>
8
4
null
>
rows
(
ordered
):
8
DROP
TABLE
TEST
;
>
ok
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/window/nth_value.sql
浏览文件 @
4f23bb18
...
...
@@ -139,8 +139,8 @@ SELECT ID, CATEGORY,
NTH_VALUE
(
CATEGORY
,
2
)
OVER
(
ORDER
BY
CATEGORY
RANGE
BETWEEN
UNBOUNDED
PRECEDING
AND
CURRENT
ROW
)
C
,
NTH_VALUE
(
CATEGORY
,
2
)
OVER
(
ORDER
BY
CATEGORY
RANGE
BETWEEN
UNBOUNDED
PRECEDING
AND
CURRENT
ROW
EXCLUDE
CURRENT
ROW
)
FROM
TEST
FETCH
FIRST
3
ROWS
ONLY
;
>
ID
CATEGORY
C
NTH_VALUE
(
CATEGORY
,
2
)
OVER
(
ORDER
BY
CATEGORY
RANGE
BETWEEN
UNBOUNDED
PRECEDING
AND
CURRENT
ROW
EXCLUDE
CURRENT
ROW
)
>
-- -------- ---- ---------------------------------------------------------------------------------------------
------------------------
>
ID
CATEGORY
C
NTH_VALUE
(
CATEGORY
,
2
)
OVER
(
ORDER
BY
CATEGORY
RANGE
UNBOUNDED
PRECEDING
EXCLUDE
CURRENT
ROW
)
>
-- -------- ---- ---------------------------------------------------------------------------------------------
>
1
1
null
null
>
2
1
1
null
>
3
1
1
1
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论