2021-01-13 22:04:19 +00:00
-- { echo }
2020-12-18 14:34:22 +00:00
set allow_experimental_window_functions = 1;
2021-01-13 22:04:19 +00:00
-- just something basic
2021-01-28 17:05:01 +00:00
select number, count() over (partition by intDiv(number, 3) order by number rows unbounded preceding) from numbers(10);
2020-12-18 00:49:18 +00:00
0 1
1 2
2 3
3 1
4 2
5 3
6 1
7 2
8 3
9 1
2021-01-13 22:04:19 +00:00
-- proper calculation across blocks
2021-01-28 17:05:01 +00:00
select number, max(number) over (partition by intDiv(number, 3) order by number desc rows unbounded preceding) from numbers(10) settings max_block_size = 2;
2020-12-18 00:49:18 +00:00
2 2
1 2
0 2
5 5
2021-01-27 00:27:40 +00:00
4 5
3 5
2020-12-18 00:49:18 +00:00
8 8
7 8
6 8
9 9
2021-01-13 22:04:19 +00:00
-- not a window function
2021-01-28 17:05:01 +00:00
select number, abs(number) over (partition by toString(intDiv(number, 3)) rows unbounded preceding) from numbers(10); -- { serverError 63 }
2021-01-13 22:04:19 +00:00
-- no partition by
2021-01-28 17:05:01 +00:00
select number, avg(number) over (order by number rows unbounded preceding) from numbers(10);
2020-12-18 00:49:18 +00:00
0 0
2020-12-22 17:46:31 +00:00
1 0.5
2020-12-18 00:49:18 +00:00
2 1
2020-12-22 17:46:31 +00:00
3 1.5
2020-12-18 00:49:18 +00:00
4 2
2020-12-22 17:46:31 +00:00
5 2.5
2020-12-18 00:49:18 +00:00
6 3
2020-12-22 17:46:31 +00:00
7 3.5
2020-12-18 00:49:18 +00:00
8 4
2020-12-22 17:46:31 +00:00
9 4.5
2021-01-13 22:04:19 +00:00
-- no order by
2021-01-28 17:05:01 +00:00
select number, quantileExact(number) over (partition by intDiv(number, 3) rows unbounded preceding) from numbers(10);
2020-12-18 00:49:18 +00:00
0 0
1 1
2 1
3 3
4 4
5 4
6 6
7 7
8 7
9 9
2021-01-13 22:04:19 +00:00
-- can add an alias after window spec
2021-01-28 17:05:01 +00:00
select number, quantileExact(number) over (partition by intDiv(number, 3) rows unbounded preceding) q from numbers(10);
2020-12-18 00:49:18 +00:00
0 0
1 1
2 1
3 3
4 4
5 4
6 6
7 7
8 7
9 9
2021-01-13 22:04:19 +00:00
-- can't reference it yet -- the window functions are calculated at the
-- last stage of select, after all other functions.
2021-01-28 17:05:01 +00:00
select q * 10, quantileExact(number) over (partition by intDiv(number, 3) rows unbounded preceding) q from numbers(10); -- { serverError 47 }
2021-01-13 22:04:19 +00:00
-- must work in WHERE if you wrap it in a subquery
2021-01-28 17:05:01 +00:00
select * from (select count(*) over (rows unbounded preceding) c from numbers(3)) where c > 0;
2020-12-25 04:59:17 +00:00
1
2
3
2021-01-13 22:04:19 +00:00
-- should work in ORDER BY
2021-01-28 17:05:01 +00:00
select number, max(number) over (partition by intDiv(number, 3) order by number desc rows unbounded preceding) m from numbers(10) order by m desc, number;
2020-12-25 03:13:30 +00:00
9 9
6 8
7 8
8 8
3 5
4 5
5 5
0 2
1 2
2 2
2021-01-13 22:04:19 +00:00
-- also works in ORDER BY if you wrap it in a subquery
2021-01-28 17:05:01 +00:00
select * from (select count(*) over (rows unbounded preceding) c from numbers(3)) order by c;
2020-12-24 04:03:33 +00:00
1
2
3
2021-01-13 22:04:19 +00:00
-- Example with window function only in ORDER BY. Here we make a rank of all
-- numbers sorted descending, and then sort by this rank descending, and must get
-- the ascending order.
2021-01-28 17:05:01 +00:00
select * from (select * from numbers(5) order by rand()) order by count() over (order by number desc rows unbounded preceding) desc;
2020-12-25 04:59:17 +00:00
0
1
2
3
4
2021-01-13 22:04:19 +00:00
-- Aggregate functions as window function arguments. This query is semantically
-- the same as the above one, only we replace `number` with
-- `any(number) group by number` and so on.
2021-01-28 17:05:01 +00:00
select * from (select * from numbers(5) order by rand()) group by number order by sum(any(number + 1)) over (order by min(number) desc rows unbounded preceding) desc;
2020-12-25 04:59:17 +00:00
0
2020-12-28 09:56:38 +00:00
1
2020-12-24 04:03:33 +00:00
2
3
2020-12-25 04:59:17 +00:00
4
2021-01-13 22:04:19 +00:00
-- some more simple cases w/aggregate functions
2021-01-28 17:05:01 +00:00
select sum(any(number)) over (rows unbounded preceding) from numbers(1);
2021-01-13 19:29:52 +00:00
0
2021-01-28 17:05:01 +00:00
select sum(any(number) + 1) over (rows unbounded preceding) from numbers(1);
2021-01-13 19:29:52 +00:00
1
2021-01-28 17:05:01 +00:00
select sum(any(number + 1)) over (rows unbounded preceding) from numbers(1);
2021-01-13 22:04:19 +00:00
1
2021-01-13 19:29:52 +00:00
-- different windows
-- an explain test would also be helpful, but it's too immature now and I don't
-- want to change reference all the time
2021-01-28 17:05:01 +00:00
select number, max(number) over (partition by intDiv(number, 3) order by number desc rows unbounded preceding), count(number) over (partition by intDiv(number, 5) order by number rows unbounded preceding) as m from numbers(31) order by number settings max_block_size = 2;
2020-12-22 01:37:45 +00:00
0 2 1
1 2 2
2 2 3
2021-01-27 00:27:40 +00:00
3 5 4
4 5 5
2020-12-22 01:37:45 +00:00
5 5 1
2021-01-27 00:27:40 +00:00
6 8 2
7 8 3
8 8 4
9 11 5
10 11 1
2020-12-22 01:37:45 +00:00
11 11 2
12 14 3
13 14 4
14 14 5
2021-01-27 00:27:40 +00:00
15 17 1
16 17 2
17 17 3
18 20 4
19 20 5
2020-12-22 01:37:45 +00:00
20 20 1
2021-01-27 00:27:40 +00:00
21 23 2
22 23 3
2020-12-22 01:37:45 +00:00
23 23 4
24 26 5
25 26 1
2021-01-27 00:27:40 +00:00
26 26 2
27 29 3
28 29 4
29 29 5
2020-12-22 01:37:45 +00:00
30 30 1
2021-01-13 22:04:19 +00:00
-- two functions over the same window
-- an explain test would also be helpful, but it's too immature now and I don't
-- want to change reference all the time
2021-01-28 17:05:01 +00:00
select number, max(number) over (partition by intDiv(number, 3) order by number desc rows unbounded preceding), count(number) over (partition by intDiv(number, 3) order by number desc rows unbounded preceding) as m from numbers(7) order by number settings max_block_size = 2;
2020-12-22 01:37:45 +00:00
0 2 3
1 2 2
2 2 1
2021-01-27 00:27:40 +00:00
3 5 3
4 5 2
2020-12-22 01:37:45 +00:00
5 5 1
6 6 1
2021-01-13 22:04:19 +00:00
-- check that we can work with constant columns
select median(x) over (partition by x) from (select 1 x);
2020-12-24 04:03:33 +00:00
1
2021-01-13 22:04:19 +00:00
-- an empty window definition is valid as well
2021-01-28 17:05:01 +00:00
select groupArray(number) over (rows unbounded preceding) from numbers(3);
2020-12-24 04:03:33 +00:00
[0]
[0,1]
[0,1,2]
2021-01-28 17:05:01 +00:00
select groupArray(number) over () from numbers(3);
[0,1,2]
[0,1,2]
[0,1,2]
2021-01-13 22:04:19 +00:00
-- This one tests we properly process the window function arguments.
-- Seen errors like 'column `1` not found' from count(1).
2021-01-28 17:05:01 +00:00
select count(1) over (rows unbounded preceding), max(number + 1) over () from numbers(3);
2020-12-24 08:49:55 +00:00
1 3
2021-01-13 22:04:19 +00:00
-- Should work in DISTINCT
2021-01-28 17:05:01 +00:00
select distinct sum(0) over (rows unbounded preceding) from numbers(2);
2020-12-25 03:13:30 +00:00
0
2021-01-28 17:05:01 +00:00
select distinct any(number) over (rows unbounded preceding) from numbers(2);
2021-01-13 22:04:19 +00:00
0
2020-12-28 09:56:38 +00:00
-- Various kinds of aliases are properly substituted into various parts of window
-- function definition.
2021-01-28 17:05:01 +00:00
with number + 1 as x select intDiv(number, 3) as y, sum(x + y) over (partition by y order by x rows unbounded preceding) from numbers(7);
2020-12-28 09:56:38 +00:00
0 1
0 3
0 6
1 5
1 11
1 18
2 9
2021-01-13 22:04:19 +00:00
-- WINDOW clause
select 1 window w1 as ();
2021-01-13 19:29:52 +00:00
1
select sum(number) over w1, sum(number) over w2
from numbers(10)
window
2021-01-28 17:05:01 +00:00
w1 as (rows unbounded preceding),
w2 as (partition by intDiv(number, 3) rows unbounded preceding)
2021-01-13 19:29:52 +00:00
;
0 0
1 1
3 3
6 3
10 7
15 12
21 6
28 13
36 21
45 9
2021-01-28 17:05:01 +00:00
-- FIXME both functions should use the same window, but they don't. Add an
-- EXPLAIN test for this.
2021-01-13 19:29:52 +00:00
select
sum(number) over w1,
2021-01-28 17:05:01 +00:00
sum(number) over (partition by intDiv(number, 3) rows unbounded preceding)
2021-01-13 19:29:52 +00:00
from numbers(10)
window
2021-01-28 17:05:01 +00:00
w1 as (partition by intDiv(number, 3) rows unbounded preceding)
2021-01-13 19:29:52 +00:00
;
0 0
1 1
3 3
3 3
7 7
12 12
6 6
13 13
21 21
9 9
2021-01-27 00:08:15 +00:00
-- RANGE frame
2021-01-28 17:05:01 +00:00
-- It's the default
select sum(number) over () from numbers(3);
3
3
3
2021-01-27 00:08:15 +00:00
-- Try some mutually prime sizes of partition, group and block, for the number
2021-01-28 17:05:01 +00:00
-- of rows that is their least common multiple + 1, so that we see all the
-- interesting corner cases.
2021-01-27 00:08:15 +00:00
select number, intDiv(number, 3) p, mod(number, 2) o, count(number) over w as c
2021-01-28 17:05:01 +00:00
from numbers(31)
2021-01-27 00:08:15 +00:00
window w as (partition by p order by o range unbounded preceding)
order by number
settings max_block_size = 5
;
0 0 0 2
1 0 1 3
2 0 0 2
3 1 1 3
4 1 0 1
5 1 1 3
6 2 0 2
7 2 1 3
8 2 0 2
9 3 1 3
10 3 0 1
11 3 1 3
12 4 0 2
13 4 1 3
14 4 0 2
15 5 1 3
16 5 0 1
17 5 1 3
18 6 0 2
19 6 1 3
20 6 0 2
21 7 1 3
22 7 0 1
23 7 1 3
24 8 0 2
25 8 1 3
26 8 0 2
27 9 1 3
28 9 0 1
29 9 1 3
2021-01-28 17:05:01 +00:00
30 10 0 1
2021-01-27 00:08:15 +00:00
select number, intDiv(number, 5) p, mod(number, 3) o, count(number) over w as c
2021-01-28 17:05:01 +00:00
from numbers(31)
2021-01-27 00:08:15 +00:00
window w as (partition by p order by o range unbounded preceding)
order by number
settings max_block_size = 2
;
0 0 0 2
1 0 1 4
2 0 2 5
3 0 0 2
4 0 1 4
5 1 2 5
6 1 0 2
7 1 1 3
8 1 2 5
9 1 0 2
10 2 1 3
11 2 2 5
12 2 0 1
13 2 1 3
14 2 2 5
15 3 0 2
16 3 1 4
17 3 2 5
18 3 0 2
19 3 1 4
20 4 2 5
21 4 0 2
22 4 1 3
23 4 2 5
24 4 0 2
25 5 1 3
26 5 2 5
27 5 0 1
28 5 1 3
29 5 2 5
2021-01-28 17:05:01 +00:00
30 6 0 1
2021-01-27 00:08:15 +00:00
select number, intDiv(number, 5) p, mod(number, 2) o, count(number) over w as c
2021-01-28 17:05:01 +00:00
from numbers(31)
2021-01-27 00:08:15 +00:00
window w as (partition by p order by o range unbounded preceding)
order by number
settings max_block_size = 3
;
0 0 0 3
1 0 1 5
2 0 0 3
3 0 1 5
4 0 0 3
5 1 1 5
6 1 0 2
7 1 1 5
8 1 0 2
9 1 1 5
10 2 0 3
11 2 1 5
12 2 0 3
13 2 1 5
14 2 0 3
15 3 1 5
16 3 0 2
17 3 1 5
18 3 0 2
19 3 1 5
20 4 0 3
21 4 1 5
22 4 0 3
23 4 1 5
24 4 0 3
25 5 1 5
26 5 0 2
27 5 1 5
28 5 0 2
29 5 1 5
2021-01-28 17:05:01 +00:00
30 6 0 1
2021-01-27 00:08:15 +00:00
select number, intDiv(number, 3) p, mod(number, 5) o, count(number) over w as c
2021-01-28 17:05:01 +00:00
from numbers(31)
2021-01-27 00:08:15 +00:00
window w as (partition by p order by o range unbounded preceding)
order by number
settings max_block_size = 2
;
0 0 0 1
1 0 1 2
2 0 2 3
3 1 3 2
4 1 4 3
5 1 0 1
6 2 1 1
7 2 2 2
8 2 3 3
9 3 4 3
10 3 0 1
11 3 1 2
12 4 2 1
13 4 3 2
14 4 4 3
15 5 0 1
16 5 1 2
17 5 2 3
18 6 3 2
19 6 4 3
20 6 0 1
21 7 1 1
22 7 2 2
23 7 3 3
24 8 4 3
25 8 0 1
26 8 1 2
27 9 2 1
28 9 3 2
29 9 4 3
2021-01-28 17:05:01 +00:00
30 10 0 1
2021-01-27 00:08:15 +00:00
select number, intDiv(number, 2) p, mod(number, 5) o, count(number) over w as c
2021-01-28 17:05:01 +00:00
from numbers(31)
2021-01-27 00:08:15 +00:00
window w as (partition by p order by o range unbounded preceding)
order by number
settings max_block_size = 3
;
0 0 0 1
1 0 1 2
2 1 2 1
3 1 3 2
4 2 4 2
5 2 0 1
6 3 1 1
7 3 2 2
8 4 3 1
9 4 4 2
10 5 0 1
11 5 1 2
12 6 2 1
13 6 3 2
14 7 4 2
15 7 0 1
16 8 1 1
17 8 2 2
18 9 3 1
19 9 4 2
20 10 0 1
21 10 1 2
22 11 2 1
23 11 3 2
24 12 4 2
25 12 0 1
26 13 1 1
27 13 2 2
28 14 3 1
29 14 4 2
2021-01-28 17:05:01 +00:00
30 15 0 1
2021-01-27 00:08:15 +00:00
select number, intDiv(number, 2) p, mod(number, 3) o, count(number) over w as c
2021-01-28 17:05:01 +00:00
from numbers(31)
2021-01-27 00:08:15 +00:00
window w as (partition by p order by o range unbounded preceding)
order by number
settings max_block_size = 5
;
0 0 0 1
1 0 1 2
2 1 2 2
3 1 0 1
4 2 1 1
5 2 2 2
6 3 0 1
7 3 1 2
8 4 2 2
9 4 0 1
10 5 1 1
11 5 2 2
12 6 0 1
13 6 1 2
14 7 2 2
15 7 0 1
16 8 1 1
17 8 2 2
18 9 0 1
19 9 1 2
20 10 2 2
21 10 0 1
22 11 1 1
23 11 2 2
24 12 0 1
25 12 1 2
26 13 2 2
27 13 0 1
28 14 1 1
29 14 2 2
2021-01-28 17:05:01 +00:00
30 15 0 1
2021-01-28 18:18:16 +00:00
-- A case where the partition end is in the current block, and the frame end
-- is triggered by the partition end.
select min(number) over (partition by p) from (select number, intDiv(number, 3) p from numbers(10));
0
0
0
3
3
3
6
6
6
9