-- -- OLAP_WINDOW -- -- Changes here should also be made to olap_window_seq.sql -- 1 -- Null window specification -- OVER () -- select row_number() over (), cn,pn,vn from sale; -- mvd 1->1 row_number | cn | pn | vn ------------+----+-----+---- 1 | 1 | 200 | 10 2 | 3 | 200 | 40 3 | 1 | 100 | 20 4 | 2 | 400 | 50 5 | 3 | 600 | 30 6 | 4 | 800 | 40 7 | 2 | 100 | 40 8 | 1 | 300 | 30 9 | 1 | 400 | 50 10 | 1 | 500 | 30 11 | 3 | 500 | 30 12 | 4 | 700 | 40 (12 rows) select rank() over (), * from sale; --error - order by req'd rank | cn | vn | pn | dt | qty | prc ------+----+----+-----+------------+------+------ 1 | 1 | 10 | 200 | 03-01-1401 | 1 | 0 1 | 1 | 20 | 100 | 05-01-1401 | 1 | 0 1 | 1 | 30 | 300 | 05-02-1401 | 1 | 0 1 | 1 | 30 | 500 | 06-01-1401 | 12 | 5 1 | 1 | 50 | 400 | 06-01-1401 | 1 | 0 1 | 2 | 40 | 100 | 01-01-1401 | 1100 | 2400 1 | 2 | 50 | 400 | 06-01-1401 | 1 | 0 1 | 3 | 30 | 500 | 06-01-1401 | 12 | 5 1 | 3 | 30 | 600 | 06-01-1401 | 12 | 5 1 | 3 | 40 | 200 | 04-01-1401 | 1 | 0 1 | 4 | 40 | 700 | 06-01-1401 | 1 | 1 1 | 4 | 40 | 800 | 06-01-1401 | 1 | 1 (12 rows) select dense_rank() over (), * from sale; --error - order by order by req'd dense_rank | cn | vn | pn | dt | qty | prc ------------+----+----+-----+------------+------+------ 1 | 1 | 10 | 200 | 03-01-1401 | 1 | 0 1 | 1 | 20 | 100 | 05-01-1401 | 1 | 0 1 | 1 | 30 | 300 | 05-02-1401 | 1 | 0 1 | 1 | 30 | 500 | 06-01-1401 | 12 | 5 1 | 1 | 50 | 400 | 06-01-1401 | 1 | 0 1 | 2 | 40 | 100 | 01-01-1401 | 1100 | 2400 1 | 2 | 50 | 400 | 06-01-1401 | 1 | 0 1 | 3 | 30 | 500 | 06-01-1401 | 12 | 5 1 | 3 | 30 | 600 | 06-01-1401 | 12 | 5 1 | 3 | 40 | 200 | 04-01-1401 | 1 | 0 1 | 4 | 40 | 700 | 06-01-1401 | 1 | 1 1 | 4 | 40 | 800 | 06-01-1401 | 1 | 1 (12 rows) -- 2 -- Plan trivial windows over various input plan types -- select row_number() over (), pn, cn, vn, dt, qty, prc from sale; -- mvd 1->1 row_number | pn | cn | vn | dt | qty | prc ------------+-----+----+----+------------+------+------ 1 | 200 | 1 | 10 | 03-01-1401 | 1 | 0 2 | 200 | 3 | 40 | 04-01-1401 | 1 | 0 3 | 100 | 1 | 20 | 05-01-1401 | 1 | 0 4 | 400 | 2 | 50 | 06-01-1401 | 1 | 0 5 | 600 | 3 | 30 | 06-01-1401 | 12 | 5 6 | 800 | 4 | 40 | 06-01-1401 | 1 | 1 7 | 100 | 2 | 40 | 01-01-1401 | 1100 | 2400 8 | 300 | 1 | 30 | 05-02-1401 | 1 | 0 9 | 400 | 1 | 50 | 06-01-1401 | 1 | 0 10 | 500 | 1 | 30 | 06-01-1401 | 12 | 5 11 | 500 | 3 | 30 | 06-01-1401 | 12 | 5 12 | 700 | 4 | 40 | 06-01-1401 | 1 | 1 (12 rows) select row_number() over (), s.pn, s.cn, s.vn, s.dt, s.qty, s.prc, c.cname, c.cloc, p.pname, p.pcolor from sale s, customer c, product p where s.cn = c.cn and s.pn = p.pn; -- mvd 1->1 row_number | pn | cn | vn | dt | qty | prc | cname | cloc | pname | pcolor ------------+-----+----+----+------------+------+------+--------------+--------------+-----------+----------- 1 | 400 | 2 | 50 | 06-01-1401 | 1 | 0 | Duncan | Forres | Justice | Clear 2 | 800 | 4 | 40 | 06-01-1401 | 1 | 1 | Witches, Inc | Lonely Heath | Fries | Grey 3 | 100 | 1 | 20 | 05-01-1401 | 1 | 0 | Macbeth | Inverness | Sword | Black 4 | 200 | 3 | 40 | 04-01-1401 | 1 | 0 | Lady Macbeth | Inverness | Dream | Black 5 | 200 | 1 | 10 | 03-01-1401 | 1 | 0 | Macbeth | Inverness | Dream | Black 6 | 600 | 3 | 30 | 06-01-1401 | 12 | 5 | Lady Macbeth | Inverness | Donuts | Chocolate 7 | 300 | 1 | 30 | 05-02-1401 | 1 | 0 | Macbeth | Inverness | Castle | Grey 8 | 400 | 1 | 50 | 06-01-1401 | 1 | 0 | Macbeth | Inverness | Justice | Clear 9 | 500 | 3 | 30 | 06-01-1401 | 12 | 5 | Lady Macbeth | Inverness | Donuts | Plain 10 | 500 | 1 | 30 | 06-01-1401 | 12 | 5 | Macbeth | Inverness | Donuts | Plain 11 | 100 | 2 | 40 | 01-01-1401 | 1100 | 2400 | Duncan | Forres | Sword | Black 12 | 700 | 4 | 40 | 06-01-1401 | 1 | 1 | Witches, Inc | Lonely Heath | Hamburger | Grey (12 rows) select row_number() over (), vn, count(*), sum(qty*prc) as amt from sale group by vn; -- mvd 1->1 row_number | vn | count | amt ------------+----+-------+--------- 1 | 40 | 4 | 2640002 2 | 20 | 1 | 0 3 | 30 | 4 | 180 4 | 50 | 2 | 0 5 | 10 | 1 | 0 (5 rows) select row_number() over (), name, loc from (select vname, vloc from vendor union select cname, cloc from customer) r(name,loc); -- mvd 1->1 row_number | name | loc ------------+--------------+-------------- 1 | Lady Macbeth | Inverness 2 | Macbeth | Inverness 3 | Duncan | Forres 4 | Macduff | Fife 5 | Witches, Inc | Lonely Heath (5 rows) select row_number() over (), s from generate_series(1,3) r(s); -- mvd 1->1 row_number | s ------------+--- 1 | 1 2 | 2 3 | 3 (3 rows) select row_number() over (), u, v from ( values (1,2),(3,4),(5,6) ) r(u,v); -- mvd 1->1 row_number | u | v ------------+---+--- 1 | 1 | 2 2 | 3 | 4 3 | 5 | 6 (3 rows) -- 3 -- Exercise WINDOW Clause -- select row_number() over (w), * from sale window w as () -- mvd 1->1 order by 1 desc; -- order 1 row_number | cn | vn | pn | dt | qty | prc ------------+----+----+-----+------------+------+------ 12 | 4 | 40 | 700 | 06-01-1401 | 1 | 1 11 | 3 | 30 | 500 | 06-01-1401 | 12 | 5 10 | 1 | 30 | 500 | 06-01-1401 | 12 | 5 9 | 1 | 50 | 400 | 06-01-1401 | 1 | 0 8 | 1 | 30 | 300 | 05-02-1401 | 1 | 0 7 | 2 | 40 | 100 | 01-01-1401 | 1100 | 2400 6 | 4 | 40 | 800 | 06-01-1401 | 1 | 1 5 | 3 | 30 | 600 | 06-01-1401 | 12 | 5 4 | 2 | 50 | 400 | 06-01-1401 | 1 | 0 3 | 1 | 20 | 100 | 05-01-1401 | 1 | 0 2 | 3 | 40 | 200 | 04-01-1401 | 1 | 0 1 | 1 | 10 | 200 | 03-01-1401 | 1 | 0 (12 rows) select row_number() over (w), * from sale order by 1 desc window w as (); --error - window can't follow order by ERROR: syntax error at or near "window" LINE 3: window w as (); ^ select count(*) over (w2) from customer window w1 as (), w2 as (w1 partition by cn); --error - can't partition if referencing ordering window ERROR: cannot override PARTITION BY clause of window "w1" LINE 4: w2 as (w1 partition by cn); ^ select count(*) over (w2) from customer window w1 as (partition by cloc order by cname), w2 as (w1 order by cn); --error - can't reorder the ordering window ERROR: cannot override ORDER BY clause of window "w1" LINE 4: w2 as (w1 order by cn); ^ select count(*) over (w2) from customer window w1 as (order by cn rows unbounded preceding), w2 as (w1); --error - ordering window can't specify framing ERROR: cannot copy window "w1" because it has a frame clause LINE 4: w2 as (w1); ^ select * from sale window w as (partition by pn), wa as (w order by cn), wb as (w order by vn), waf as (wa rows between 2 preceding and 3 preceding), wbf as (wb range between 2 preceding and 3 preceding); --mvd 3->1 cn | vn | pn | dt | qty | prc ----+----+-----+------------+------+------ 2 | 40 | 100 | 01-01-1401 | 1100 | 2400 1 | 30 | 300 | 05-02-1401 | 1 | 0 1 | 50 | 400 | 06-01-1401 | 1 | 0 1 | 30 | 500 | 06-01-1401 | 12 | 5 3 | 30 | 500 | 06-01-1401 | 12 | 5 4 | 40 | 700 | 06-01-1401 | 1 | 1 1 | 10 | 200 | 03-01-1401 | 1 | 0 3 | 40 | 200 | 04-01-1401 | 1 | 0 1 | 20 | 100 | 05-01-1401 | 1 | 0 2 | 50 | 400 | 06-01-1401 | 1 | 0 3 | 30 | 600 | 06-01-1401 | 12 | 5 4 | 40 | 800 | 06-01-1401 | 1 | 1 (12 rows) select * from customer window w as (partition by cn), w as (w order by cname); --error - can't refer to window in its definition ERROR: window "w" is already defined LINE 4: w as (w order by cname); ^ select * from customer window w as (w order by cname); --error - can't refer to window in its definition ERROR: window "w" does not exist LINE 2: window w as (w order by cname); ^ -- test the frame parser select cn, count(*) over (order by cn range '1'::interval preceding) from customer; -- error, type mismatch ERROR: window specification RANGE parameter type must be coercible to ORDER BY column type select cn, count(*) over (order by cn range between '-11' preceding and '-2' following) from customer; -- error, negative values not permitted ERROR: RANGE parameter cannot be negative LINE 2: count(*) over (order by cn range between '-11' preceding a... ^ select cn, sum(cn) over (order by cn range NULL preceding) from customer; -- we don't permit NULL ERROR: RANGE parameter cannot be NULL LINE 2: sum(cn) over (order by cn range NULL preceding) ^ select cn, sum(cn) over (order by cn range '1'::float8 preceding) from customer; -- this, however, should work cn | sum ----+----- 1 | 1 2 | 3 3 | 5 4 | 7 (4 rows) -- 4 -- Partitioned, non-ordered window specifications -- OVER (PARTITION BY ...) -- -- ! select row_number() over (partition by cn), cn, pn from sale; -- mvd 2->1 row_number | cn | pn ------------+----+----- 1 | 2 | 400 2 | 2 | 100 1 | 4 | 700 2 | 4 | 800 1 | 1 | 200 2 | 1 | 500 3 | 1 | 400 4 | 1 | 300 5 | 1 | 100 1 | 3 | 600 2 | 3 | 500 3 | 3 | 200 (12 rows) select row_number() over (partition by pn, cn), cn, pn from sale; -- mvd 2,3->1 row_number | cn | pn ------------+----+----- 1 | 2 | 100 1 | 1 | 300 1 | 1 | 400 1 | 1 | 500 1 | 3 | 500 1 | 4 | 700 1 | 1 | 100 1 | 1 | 200 1 | 3 | 200 1 | 2 | 400 1 | 3 | 600 1 | 4 | 800 (12 rows) select rank() over (partition by cn), cn, pn from sale; --error - rank requires ordering rank | cn | pn ------+----+----- 1 | 1 | 100 1 | 1 | 200 1 | 1 | 300 1 | 1 | 400 1 | 1 | 500 1 | 2 | 100 1 | 2 | 400 1 | 3 | 200 1 | 3 | 500 1 | 3 | 600 1 | 4 | 700 1 | 4 | 800 (12 rows) select dense_rank() over (partition by cn), cn, pn from sale; --error - dense_rank requires ordering dense_rank | cn | pn ------------+----+----- 1 | 1 | 100 1 | 1 | 200 1 | 1 | 300 1 | 1 | 400 1 | 1 | 500 1 | 2 | 100 1 | 2 | 400 1 | 3 | 200 1 | 3 | 500 1 | 3 | 600 1 | 4 | 700 1 | 4 | 800 (12 rows) select row_number() over (partition by pname, cname), pname, cname from sale s, customer c, product p where s.cn = c.cn and s.pn = p.pn; -- mvd 2,3->1 row_number | pname | cname ------------+-----------+-------------- 1 | Donuts | Lady Macbeth 2 | Donuts | Lady Macbeth 1 | Donuts | Macbeth 1 | Dream | Lady Macbeth 1 | Dream | Macbeth 1 | Justice | Macbeth 1 | Sword | Macbeth 1 | Castle | Macbeth 1 | Fries | Witches, Inc 1 | Hamburger | Witches, Inc 1 | Justice | Duncan 1 | Sword | Duncan (12 rows) select row_number() over (partition by vn), vn, count(*) from sale group by vn; -- mvd 2->1 row_number | vn | count ------------+----+------- 1 | 10 | 1 1 | 20 | 1 1 | 30 | 4 1 | 40 | 4 1 | 50 | 2 (5 rows) select row_number() over (partition by count(*)), vn, count(*) from sale group by vn; -- mvd 3->1 row_number | vn | count ------------+----+------- 1 | 20 | 1 2 | 10 | 1 1 | 50 | 2 1 | 30 | 4 2 | 40 | 4 (5 rows) -- 5 -- Ordered, non-partitioned window specifications -- OVER (ORDER BY ...) -- select row_number() over (order by cn), cn, pn from sale; -- mvd 2->1 row_number | cn | pn ------------+----+----- 1 | 1 | 100 2 | 1 | 200 3 | 1 | 400 4 | 1 | 300 5 | 1 | 500 6 | 2 | 100 7 | 2 | 400 8 | 3 | 600 9 | 3 | 200 10 | 3 | 500 11 | 4 | 700 12 | 4 | 800 (12 rows) select row_number() over (order by pn desc), cn, pn from sale; -- mvd 3->1 row_number | cn | pn ------------+----+----- 1 | 4 | 800 2 | 4 | 700 3 | 3 | 600 4 | 1 | 500 5 | 3 | 500 6 | 1 | 400 7 | 2 | 400 8 | 1 | 300 9 | 3 | 200 10 | 1 | 200 11 | 1 | 100 12 | 2 | 100 (12 rows) select row_number() over (order by pn, cn desc), cn, pn from sale; -- mvd 2,3->1 row_number | cn | pn ------------+----+----- 1 | 2 | 100 2 | 1 | 100 3 | 3 | 200 4 | 1 | 200 5 | 1 | 300 6 | 2 | 400 7 | 1 | 400 8 | 3 | 500 9 | 1 | 500 10 | 3 | 600 11 | 4 | 700 12 | 4 | 800 (12 rows) select rank() over (order by cn), cn, pn from sale; -- mvd 1->-- mvd rank | cn | pn ------+----+----- 1 | 1 | 100 1 | 1 | 200 1 | 1 | 400 1 | 1 | 300 1 | 1 | 500 6 | 2 | 100 6 | 2 | 400 8 | 3 | 600 8 | 3 | 200 8 | 3 | 500 11 | 4 | 700 11 | 4 | 800 (12 rows) select rank() over (order by pn desc), cn, pn from sale; -- mvd 1->2,3 rank | cn | pn ------+----+----- 1 | 4 | 800 2 | 4 | 700 3 | 3 | 600 4 | 1 | 500 4 | 3 | 500 6 | 1 | 400 6 | 2 | 400 8 | 1 | 300 9 | 3 | 200 9 | 1 | 200 11 | 1 | 100 11 | 2 | 100 (12 rows) select rank() over (order by pn, cn desc), cn, pn from sale; -- mvd 1->2,3 rank | cn | pn ------+----+----- 1 | 2 | 100 2 | 1 | 100 3 | 3 | 200 4 | 1 | 200 5 | 1 | 300 6 | 2 | 400 7 | 1 | 400 8 | 3 | 500 9 | 1 | 500 10 | 3 | 600 11 | 4 | 700 12 | 4 | 800 (12 rows) select dense_rank() over (order by cn), cn, pn from sale; -- mvd 1->2,3 dense_rank | cn | pn ------------+----+----- 1 | 1 | 100 1 | 1 | 200 1 | 1 | 400 1 | 1 | 300 1 | 1 | 500 2 | 2 | 100 2 | 2 | 400 3 | 3 | 600 3 | 3 | 200 3 | 3 | 500 4 | 4 | 700 4 | 4 | 800 (12 rows) select dense_rank() over (order by pn desc), cn, pn from sale; -- mvd 1->2,3 dense_rank | cn | pn ------------+----+----- 1 | 4 | 800 2 | 4 | 700 3 | 3 | 600 4 | 1 | 500 4 | 3 | 500 5 | 1 | 400 5 | 2 | 400 6 | 1 | 300 7 | 3 | 200 7 | 1 | 200 8 | 1 | 100 8 | 2 | 100 (12 rows) select dense_rank() over (order by pn, cn desc), cn, pn from sale; -- mvd 1->2,3 dense_rank | cn | pn ------------+----+----- 1 | 2 | 100 2 | 1 | 100 3 | 3 | 200 4 | 1 | 200 5 | 1 | 300 6 | 2 | 400 7 | 1 | 400 8 | 3 | 500 9 | 1 | 500 10 | 3 | 600 11 | 4 | 700 12 | 4 | 800 (12 rows) select rank() over (w), cn, pn from sale window w as (order by cn); -- mvd 1->2,3 rank | cn | pn ------+----+----- 1 | 1 | 100 1 | 1 | 200 1 | 1 | 400 1 | 1 | 300 1 | 1 | 500 6 | 2 | 100 6 | 2 | 400 8 | 3 | 600 8 | 3 | 200 8 | 3 | 500 11 | 4 | 700 11 | 4 | 800 (12 rows) select rank() over (w), cn, pn from sale window w as (order by pn desc); -- mvd 1->2,3 rank | cn | pn ------+----+----- 1 | 4 | 800 2 | 4 | 700 3 | 3 | 600 4 | 1 | 500 4 | 3 | 500 6 | 1 | 400 6 | 2 | 400 8 | 1 | 300 9 | 3 | 200 9 | 1 | 200 11 | 1 | 100 11 | 2 | 100 (12 rows) select rank() over (w), cn, pn from sale window w as (order by pn, cn desc); -- mvd 1->2,3 rank | cn | pn ------+----+----- 1 | 2 | 100 2 | 1 | 100 3 | 3 | 200 4 | 1 | 200 5 | 1 | 300 6 | 2 | 400 7 | 1 | 400 8 | 3 | 500 9 | 1 | 500 10 | 3 | 600 11 | 4 | 700 12 | 4 | 800 (12 rows) select row_number() over (order by pname, cname) from sale s, customer c, product p where s.cn = c.cn and s.pn = p.pn; -- mvd 1->1 row_number ------------ 1 2 3 4 5 6 7 8 9 10 11 12 (12 rows) select row_number() over (order by vn), vn, count(*) from sale group by vn; -- mvd 2->1 row_number | vn | count ------------+----+------- 1 | 10 | 1 2 | 20 | 1 3 | 30 | 4 4 | 40 | 4 5 | 50 | 2 (5 rows) select row_number() over (order by count(*)), vn, count(*) from sale group by vn; -- mvd 3->1 row_number | vn | count ------------+----+------- 1 | 20 | 1 2 | 10 | 1 3 | 50 | 2 4 | 40 | 4 5 | 30 | 4 (5 rows) -- Test NULLS FIRST/LAST in window clauses create table tbl_with_nulls_seq (t text, a int, b int); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 't' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into tbl_with_nulls_seq values ( 'a', 1, 10), ( 'b', 1, 10), ( 'c', 1, 10), ( 'd', 2, 10), ( 'e', 2, 20), ( 'f', 2, 20), ( 'g', NULL, 20), ( 'h', NULL, 20), ( 'i', NULL, 30); select t, a, b, first_value(t) over (order by a nulls first, t), first_value(t) over (order by a nulls last, t), first_value(t) over (partition by b order by a nulls first, t), first_value(t) over (partition by b order by a nulls last, t) from tbl_with_nulls_seq order by t; t | a | b | first_value | first_value | first_value | first_value ---+---+----+-------------+-------------+-------------+------------- a | 1 | 10 | g | a | a | a b | 1 | 10 | g | a | a | a c | 1 | 10 | g | a | a | a d | 2 | 10 | g | a | a | a e | 2 | 20 | g | a | g | e f | 2 | 20 | g | a | g | e g | | 20 | g | a | g | e h | | 20 | g | a | g | e i | | 30 | g | a | i | i (9 rows) -- Same with explicitly named window select t, a, b, first_value(t) over (w1), first_value(t) over (w2), first_value(t) over (w3), first_value(t) over (w4) from tbl_with_nulls_seq window w1 as (order by a nulls first, t), w2 as (order by a nulls last, t), w3 as (partition by b order by a nulls first, t), w4 as (partition by b order by a nulls last, t) order by t; t | a | b | first_value | first_value | first_value | first_value ---+---+----+-------------+-------------+-------------+------------- a | 1 | 10 | g | a | a | a b | 1 | 10 | g | a | a | a c | 1 | 10 | g | a | a | a d | 2 | 10 | g | a | a | a e | 2 | 20 | g | a | g | e f | 2 | 20 | g | a | g | e g | | 20 | g | a | g | e h | | 20 | g | a | g | e i | | 30 | g | a | i | i (9 rows) -- X -- Miscellaneous (e.g. old bugs, etc.) -- -- Why was this here? We can't guarantee all correct answers will pass! --select -- cn*100 + row_number() over (), -- cname, -- row_number() over () - 1, -- cn --from customer; -- mvd 4->1,3 -- ! select row_number() over (), a,b from ( select cn, count(*) from sale group by cn ) r(a,b); -- mvd 1->1 row_number | a | b ------------+---+--- 1 | 3 | 3 2 | 1 | 5 3 | 2 | 2 4 | 4 | 2 (4 rows) select * from ( select row_number() over () from customer ) r(a), ( select row_number() over () from sale ) s(a) where s.a = r.a; a | a ---+--- 1 | 1 2 | 2 3 | 3 4 | 4 (4 rows) select row_number() over (w), rank() over (w), dense_rank() over (w), * from sale window w as (order by cn); -- mvd 4->1; 4->2; 4->3 row_number | rank | dense_rank | cn | vn | pn | dt | qty | prc ------------+------+------------+----+----+-----+------------+------+------ 1 | 1 | 1 | 1 | 20 | 100 | 05-01-1401 | 1 | 0 2 | 1 | 1 | 1 | 10 | 200 | 03-01-1401 | 1 | 0 3 | 1 | 1 | 1 | 50 | 400 | 06-01-1401 | 1 | 0 4 | 1 | 1 | 1 | 30 | 300 | 05-02-1401 | 1 | 0 5 | 1 | 1 | 1 | 30 | 500 | 06-01-1401 | 12 | 5 6 | 6 | 2 | 2 | 40 | 100 | 01-01-1401 | 1100 | 2400 7 | 6 | 2 | 2 | 50 | 400 | 06-01-1401 | 1 | 0 8 | 8 | 3 | 3 | 30 | 600 | 06-01-1401 | 12 | 5 9 | 8 | 3 | 3 | 40 | 200 | 04-01-1401 | 1 | 0 10 | 8 | 3 | 3 | 30 | 500 | 06-01-1401 | 12 | 5 11 | 11 | 4 | 4 | 40 | 700 | 06-01-1401 | 1 | 1 12 | 11 | 4 | 4 | 40 | 800 | 06-01-1401 | 1 | 1 (12 rows) select cn, row_number() over (w), count(*) over (w), rank() over (w), dense_rank() over (w), vn from sale window w as (partition by cn order by vn); -- mvd 1,4->2 cn | row_number | count | rank | dense_rank | vn ----+------------+-------+------+------------+---- 1 | 1 | 1 | 1 | 1 | 10 1 | 2 | 2 | 2 | 2 | 20 1 | 3 | 4 | 3 | 3 | 30 1 | 4 | 4 | 3 | 3 | 30 1 | 5 | 5 | 5 | 4 | 50 3 | 1 | 2 | 1 | 1 | 30 3 | 2 | 2 | 1 | 1 | 30 3 | 3 | 3 | 3 | 2 | 40 2 | 1 | 1 | 1 | 1 | 40 2 | 2 | 2 | 2 | 2 | 50 4 | 1 | 2 | 1 | 1 | 40 4 | 2 | 2 | 1 | 1 | 40 (12 rows) select cn,vn, rank() over (order by cn), rank() over (order by cn,vn) from sale; cn | vn | rank | rank ----+----+------+------ 1 | 10 | 1 | 1 1 | 20 | 1 | 2 1 | 30 | 1 | 3 1 | 30 | 1 | 3 1 | 50 | 1 | 5 2 | 40 | 6 | 6 2 | 50 | 6 | 7 3 | 30 | 8 | 8 3 | 30 | 8 | 8 3 | 40 | 8 | 10 4 | 40 | 11 | 11 4 | 40 | 11 | 11 (12 rows) -- ! select cn,vn,pn, row_number() over (partition by cn), rank() over (partition by cn order by vn), rank() over (partition by cn order by vn,pn) from sale; -- mvd 1->4 cn | vn | pn | row_number | rank | rank ----+----+-----+------------+------+------ 1 | 10 | 200 | 1 | 1 | 1 1 | 20 | 100 | 2 | 2 | 2 1 | 30 | 300 | 3 | 3 | 3 1 | 30 | 500 | 4 | 3 | 4 1 | 50 | 400 | 5 | 5 | 5 3 | 30 | 500 | 1 | 1 | 1 3 | 30 | 600 | 2 | 1 | 2 3 | 40 | 200 | 3 | 3 | 3 2 | 40 | 100 | 1 | 1 | 1 2 | 50 | 400 | 2 | 2 | 2 4 | 40 | 700 | 1 | 1 | 1 4 | 40 | 800 | 2 | 1 | 2 (12 rows) select cn,vn, row_number() over (partition by cn,vn), cn,vn, rank() over (partition by cn,vn order by vn), cn,vn,pn, rank() over (partition by cn,vn order by vn,pn) from sale; -- mvd 1,2->3 cn | vn | row_number | cn | vn | rank | cn | vn | pn | rank ----+----+------------+----+----+------+----+----+-----+------ 1 | 10 | 1 | 1 | 10 | 1 | 1 | 10 | 200 | 1 1 | 20 | 1 | 1 | 20 | 1 | 1 | 20 | 100 | 1 1 | 30 | 1 | 1 | 30 | 1 | 1 | 30 | 300 | 1 1 | 30 | 2 | 1 | 30 | 1 | 1 | 30 | 500 | 2 1 | 50 | 1 | 1 | 50 | 1 | 1 | 50 | 400 | 1 3 | 30 | 1 | 3 | 30 | 1 | 3 | 30 | 500 | 1 3 | 30 | 2 | 3 | 30 | 1 | 3 | 30 | 600 | 2 3 | 40 | 1 | 3 | 40 | 1 | 3 | 40 | 200 | 1 2 | 40 | 1 | 2 | 40 | 1 | 2 | 40 | 100 | 1 2 | 50 | 1 | 2 | 50 | 1 | 2 | 50 | 400 | 1 4 | 40 | 1 | 4 | 40 | 1 | 4 | 40 | 700 | 1 4 | 40 | 2 | 4 | 40 | 1 | 4 | 40 | 800 | 2 (12 rows) select dense_rank() over (order by pname, cname), cname, pname from sale s, customer c, product p where s.cn = c.cn and s.pn = p.pn; dense_rank | cname | pname ------------+--------------+----------- 1 | Macbeth | Castle 2 | Lady Macbeth | Donuts 2 | Lady Macbeth | Donuts 3 | Macbeth | Donuts 4 | Lady Macbeth | Dream 5 | Macbeth | Dream 6 | Witches, Inc | Fries 7 | Witches, Inc | Hamburger 8 | Duncan | Justice 9 | Macbeth | Justice 10 | Duncan | Sword 11 | Macbeth | Sword (12 rows) select pn, cn, prc*qty, row_number() over (partition by pn), avg(prc*qty) over (partition by pn), avg(prc*qty) over (partition by pn order by cn), percent_rank() over (partition by pn order by cn), rank() over (partition by pn order by cn) from sale; -- mvd 1->4 pn | cn | ?column? | row_number | avg | avg | percent_rank | rank -----+----+----------+------------+---------+---------+--------------+------ 300 | 1 | 0 | 1 | 0 | 0 | 0 | 1 400 | 1 | 0 | 1 | 0 | 0 | 0 | 1 400 | 2 | 0 | 2 | 0 | 0 | 1 | 2 500 | 1 | 60 | 1 | 60 | 60 | 0 | 1 500 | 3 | 60 | 2 | 60 | 60 | 1 | 2 800 | 4 | 1 | 1 | 1 | 1 | 0 | 1 100 | 1 | 0 | 1 | 1320000 | 0 | 0 | 1 100 | 2 | 2640000 | 2 | 1320000 | 1320000 | 1 | 2 200 | 1 | 0 | 1 | 0 | 0 | 0 | 1 200 | 3 | 0 | 2 | 0 | 0 | 1 | 2 600 | 3 | 60 | 1 | 60 | 60 | 0 | 1 700 | 4 | 1 | 1 | 1 | 1 | 0 | 1 (12 rows) select pn, row_number() over (partition by pn), avg(pn) over (partition by pn) from sale; -- mvd 1->2 pn | row_number | avg -----+------------+---------------------- 300 | 1 | 300.0000000000000000 400 | 1 | 400.0000000000000000 400 | 2 | 400.0000000000000000 500 | 1 | 500.0000000000000000 500 | 2 | 500.0000000000000000 800 | 1 | 800.0000000000000000 100 | 1 | 100.0000000000000000 100 | 2 | 100.0000000000000000 200 | 1 | 200.0000000000000000 200 | 2 | 200.0000000000000000 600 | 1 | 600.0000000000000000 700 | 1 | 700.0000000000000000 (12 rows) select pn, row_number() over (partition by pn), avg(pn) over (partition by pn) from sale order by pn; -- mvd 1->2 pn | row_number | avg -----+------------+---------------------- 300 | 1 | 300.0000000000000000 400 | 1 | 400.0000000000000000 400 | 2 | 400.0000000000000000 500 | 1 | 500.0000000000000000 500 | 2 | 500.0000000000000000 800 | 1 | 800.0000000000000000 100 | 1 | 100.0000000000000000 100 | 2 | 100.0000000000000000 200 | 1 | 200.0000000000000000 200 | 2 | 200.0000000000000000 600 | 1 | 600.0000000000000000 700 | 1 | 700.0000000000000000 (12 rows) select cn, row_number() over (partition by cn), avg(cn) over (partition by cn) from sale; -- mvd 1->2 cn | row_number | avg ----+------------+------------------------ 1 | 1 | 1.00000000000000000000 1 | 2 | 1.00000000000000000000 1 | 3 | 1.00000000000000000000 1 | 4 | 1.00000000000000000000 1 | 5 | 1.00000000000000000000 3 | 1 | 3.0000000000000000 3 | 2 | 3.0000000000000000 3 | 3 | 3.0000000000000000 2 | 1 | 2.0000000000000000 2 | 2 | 2.0000000000000000 4 | 1 | 4.0000000000000000 4 | 2 | 4.0000000000000000 (12 rows) select cn, row_number() over (partition by cn) from sale; -- mvd 1->2 cn | row_number ----+------------ 1 | 1 1 | 2 1 | 3 1 | 4 1 | 5 3 | 1 3 | 2 3 | 3 2 | 1 2 | 2 4 | 1 4 | 2 (12 rows) -- ! select cn, vn, pn, row_number() over (partition by cn), row_number() over (partition by vn), row_number() over (partition by pn) from sale; -- mvd 1->4; 2->5; 3->6 cn | vn | pn | row_number | row_number | row_number ----+----+-----+------------+------------+------------ 1 | 10 | 200 | 1 | 1 | 2 1 | 20 | 100 | 2 | 1 | 1 1 | 30 | 500 | 3 | 1 | 2 1 | 50 | 400 | 4 | 1 | 2 1 | 30 | 300 | 5 | 3 | 1 3 | 30 | 600 | 1 | 4 | 1 3 | 40 | 200 | 2 | 1 | 1 3 | 30 | 500 | 3 | 2 | 1 2 | 50 | 400 | 1 | 2 | 1 2 | 40 | 100 | 2 | 2 | 2 4 | 40 | 800 | 1 | 4 | 1 4 | 40 | 700 | 2 | 3 | 1 (12 rows) select cn, vn, pn, avg(qty) over (partition by cn) from sale; --mvd 1->4 cn | vn | pn | avg ----+----+-----+------------------------ 1 | 10 | 200 | 3.2000000000000000 1 | 30 | 500 | 3.2000000000000000 1 | 50 | 400 | 3.2000000000000000 1 | 30 | 300 | 3.2000000000000000 1 | 20 | 100 | 3.2000000000000000 3 | 30 | 600 | 8.3333333333333333 3 | 30 | 500 | 8.3333333333333333 3 | 40 | 200 | 8.3333333333333333 2 | 40 | 100 | 550.5000000000000000 2 | 50 | 400 | 550.5000000000000000 4 | 40 | 800 | 1.00000000000000000000 4 | 40 | 700 | 1.00000000000000000000 (12 rows) select cn, vn, pn, avg(qty) over (partition by vn) from sale; --mvd 2->4 cn | vn | pn | avg ----+----+-----+------------------------ 1 | 10 | 200 | 1.00000000000000000000 1 | 20 | 100 | 1.00000000000000000000 3 | 30 | 500 | 9.2500000000000000 1 | 30 | 300 | 9.2500000000000000 1 | 30 | 500 | 9.2500000000000000 3 | 30 | 600 | 9.2500000000000000 3 | 40 | 200 | 275.7500000000000000 4 | 40 | 700 | 275.7500000000000000 2 | 40 | 100 | 275.7500000000000000 4 | 40 | 800 | 275.7500000000000000 1 | 50 | 400 | 1.00000000000000000000 2 | 50 | 400 | 1.00000000000000000000 (12 rows) -- ! select avg(qty) over (partition by cn) from sale; avg ------------------------ 550.5000000000000000 550.5000000000000000 1.00000000000000000000 1.00000000000000000000 3.2000000000000000 3.2000000000000000 3.2000000000000000 3.2000000000000000 3.2000000000000000 8.3333333333333333 8.3333333333333333 8.3333333333333333 (12 rows) select ntile(3) over (order by cn) from sale; ntile ------- 1 1 1 1 2 2 2 2 3 3 3 3 (12 rows) select dt, ntile(5) over (order by dt) from sale; dt | ntile ------------+------- 01-01-1401 | 1 03-01-1401 | 1 04-01-1401 | 1 05-01-1401 | 2 05-02-1401 | 2 06-01-1401 | 2 06-01-1401 | 3 06-01-1401 | 3 06-01-1401 | 4 06-01-1401 | 4 06-01-1401 | 5 06-01-1401 | 5 (12 rows) -- ! select cn, dt, ntile(3) over (partition by cn order by dt) from sale; -- mvd 1,2->3 cn | dt | ntile ----+------------+------- 1 | 03-01-1401 | 1 1 | 05-01-1401 | 1 1 | 05-02-1401 | 2 1 | 06-01-1401 | 2 1 | 06-01-1401 | 3 3 | 04-01-1401 | 1 3 | 06-01-1401 | 2 3 | 06-01-1401 | 3 2 | 01-01-1401 | 1 2 | 06-01-1401 | 2 4 | 06-01-1401 | 1 4 | 06-01-1401 | 2 (12 rows) -- ! select cn, dt, ntile(3) over (partition by cn order by dt), sum(prc) over (order by cn, dt) from sale; -- mvd 1,2->3 cn | dt | ntile | sum ----+------------+-------+------ 1 | 03-01-1401 | 1 | 0 1 | 05-01-1401 | 1 | 0 1 | 05-02-1401 | 2 | 0 1 | 06-01-1401 | 3 | 5 1 | 06-01-1401 | 2 | 5 2 | 01-01-1401 | 1 | 2405 2 | 06-01-1401 | 2 | 2405 3 | 04-01-1401 | 1 | 2405 3 | 06-01-1401 | 2 | 2415 3 | 06-01-1401 | 3 | 2415 4 | 06-01-1401 | 1 | 2417 4 | 06-01-1401 | 2 | 2417 (12 rows) -- ! select cn, dt, percent_rank() over (partition by cn order by dt), sum(prc) over (order by cn, dt) from sale; -- mvd 1,2->3; 1,2->4 cn | dt | percent_rank | sum ----+------------+--------------+------ 1 | 03-01-1401 | 0 | 0 1 | 05-01-1401 | 0.25 | 0 1 | 05-02-1401 | 0.5 | 0 1 | 06-01-1401 | 0.75 | 5 1 | 06-01-1401 | 0.75 | 5 2 | 01-01-1401 | 0 | 2405 2 | 06-01-1401 | 1 | 2405 3 | 04-01-1401 | 0 | 2405 3 | 06-01-1401 | 0.5 | 2415 3 | 06-01-1401 | 0.5 | 2415 4 | 06-01-1401 | 0 | 2417 4 | 06-01-1401 | 0 | 2417 (12 rows) select grouping(cn, vn, pn) as gr, cn, vn, pn, sum(qty*prc), rank() over (partition by cn order by sum(qty*prc)) from sale group by rollup(cn,vn,pn) order by 2 desc, 5; -- order 2,5 gr | cn | vn | pn | sum | rank ----+----+----+-----+---------+------ 7 | | | | 2640182 | 1 0 | 4 | 40 | 700 | 1 | 1 0 | 4 | 40 | 800 | 1 | 1 1 | 4 | 40 | | 2 | 3 3 | 4 | | | 2 | 3 0 | 3 | 40 | 200 | 0 | 1 1 | 3 | 40 | | 0 | 1 0 | 3 | 30 | 600 | 60 | 3 0 | 3 | 30 | 500 | 60 | 3 1 | 3 | 30 | | 120 | 5 3 | 3 | | | 120 | 5 0 | 2 | 50 | 400 | 0 | 1 1 | 2 | 50 | | 0 | 1 0 | 2 | 40 | 100 | 2640000 | 3 3 | 2 | | | 2640000 | 3 1 | 2 | 40 | | 2640000 | 3 1 | 1 | 10 | | 0 | 1 1 | 1 | 20 | | 0 | 1 0 | 1 | 20 | 100 | 0 | 1 0 | 1 | 10 | 200 | 0 | 1 1 | 1 | 50 | | 0 | 1 0 | 1 | 30 | 300 | 0 | 1 0 | 1 | 50 | 400 | 0 | 1 0 | 1 | 30 | 500 | 60 | 8 1 | 1 | 30 | | 60 | 8 3 | 1 | | | 60 | 8 (26 rows) select grouping(cn, vn, pn) as gr, cn, vn, pn, sum(qty*prc), rank() over (partition by cn order by sum(qty*prc)) from sale group by rollup(cn,vn,pn) order by 2, 5; -- order 2,5 gr | cn | vn | pn | sum | rank ----+----+----+-----+---------+------ 1 | 1 | 10 | | 0 | 1 0 | 1 | 10 | 200 | 0 | 1 0 | 1 | 50 | 400 | 0 | 1 1 | 1 | 50 | | 0 | 1 0 | 1 | 30 | 300 | 0 | 1 0 | 1 | 20 | 100 | 0 | 1 1 | 1 | 20 | | 0 | 1 3 | 1 | | | 60 | 8 0 | 1 | 30 | 500 | 60 | 8 1 | 1 | 30 | | 60 | 8 0 | 2 | 50 | 400 | 0 | 1 1 | 2 | 50 | | 0 | 1 0 | 2 | 40 | 100 | 2640000 | 3 3 | 2 | | | 2640000 | 3 1 | 2 | 40 | | 2640000 | 3 0 | 3 | 40 | 200 | 0 | 1 1 | 3 | 40 | | 0 | 1 0 | 3 | 30 | 600 | 60 | 3 0 | 3 | 30 | 500 | 60 | 3 1 | 3 | 30 | | 120 | 5 3 | 3 | | | 120 | 5 0 | 4 | 40 | 700 | 1 | 1 0 | 4 | 40 | 800 | 1 | 1 1 | 4 | 40 | | 2 | 3 3 | 4 | | | 2 | 3 7 | | | | 2640182 | 1 (26 rows) select cn, vn, pn, rank() over (partition by vn order by cn) from sale; --mvd 2->4 cn | vn | pn | rank ----+----+-----+------ 1 | 10 | 200 | 1 1 | 20 | 100 | 1 1 | 30 | 500 | 1 1 | 30 | 300 | 1 3 | 30 | 600 | 3 3 | 30 | 500 | 3 2 | 40 | 100 | 1 3 | 40 | 200 | 2 4 | 40 | 800 | 3 4 | 40 | 700 | 3 1 | 50 | 400 | 1 2 | 50 | 400 | 2 (12 rows) select row_number() over (partition by vn), cn, vn, pn, rank() over (partition by vn order by cn) from sale; -- mvd 3->1 row_number | cn | vn | pn | rank ------------+----+----+-----+------ 1 | 1 | 10 | 200 | 1 1 | 1 | 20 | 100 | 1 1 | 1 | 30 | 500 | 1 2 | 1 | 30 | 300 | 1 3 | 3 | 30 | 600 | 3 4 | 3 | 30 | 500 | 3 1 | 2 | 40 | 100 | 1 2 | 3 | 40 | 200 | 2 3 | 4 | 40 | 800 | 3 4 | 4 | 40 | 700 | 3 1 | 1 | 50 | 400 | 1 2 | 2 | 50 | 400 | 2 (12 rows) select row_number() over (partition by pn), cn, vn, pn, rank() over (partition by vn order by cn) from sale; -- mvd 4->1 row_number | cn | vn | pn | rank ------------+----+----+-----+------ 1 | 1 | 30 | 300 | 1 1 | 2 | 50 | 400 | 2 2 | 1 | 50 | 400 | 1 1 | 1 | 30 | 500 | 1 2 | 3 | 30 | 500 | 3 1 | 4 | 40 | 800 | 3 1 | 2 | 40 | 100 | 1 2 | 1 | 20 | 100 | 1 1 | 1 | 10 | 200 | 1 2 | 3 | 40 | 200 | 2 1 | 3 | 30 | 600 | 3 1 | 4 | 40 | 700 | 3 (12 rows) select cname, rank() over (partition by sale.cn order by pn), rank() over (partition by sale.cn order by vn) from sale, customer where sale.cn = customer.cn; -- mvd 1->2,3 cname | rank | rank --------------+------+------ Macbeth | 2 | 1 Macbeth | 1 | 2 Macbeth | 3 | 3 Macbeth | 5 | 3 Macbeth | 4 | 5 Lady Macbeth | 3 | 1 Lady Macbeth | 2 | 1 Lady Macbeth | 1 | 3 Duncan | 1 | 1 Duncan | 2 | 2 Witches, Inc | 2 | 1 Witches, Inc | 1 | 1 (12 rows) -- Check that we invert count() correctly. count() is a special case -- because when not invoked as count(*), it uses "any" as an argument. -- This can trip us up. SELECT sale.pn, COUNT(sale.pn) OVER(order by sale.pn) FROM sale; pn | count -----+------- 100 | 2 100 | 2 200 | 4 200 | 4 300 | 5 400 | 7 400 | 7 500 | 9 500 | 9 600 | 10 700 | 11 800 | 12 (12 rows) -- Reject DISTINCT qualified aggs when an ORDER BY is present SELECT count(distinct sale.pn) OVER (order by sale.pn) from sale; ERROR: DISTINCT cannot be used with window specification containing an ORDER BY clause LINE 1: SELECT count(distinct sale.pn) OVER (order by sale.pn) from ... ^ -- Aggregate nesting -- create table olap_tmp_for_window_seq(g integer, h integer, i integer, x integer); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'g' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into olap_tmp_for_window_seq values (9,1,1,1), (9,1,1,0), (9,1,1,1), (9,1,1,0), (9,1,2,1), (9,1,2,0), (9,1,2,1), (9,1,2,0), (9,4,1,1), (9,4,1,0), (9,4,1,1), (9,4,1,0), (9,4,2,1), (9,4,2,0), (9,4,2,1), (9,4,2,0), (9,1,1,1), (9,1,1,0), (9,1,1,1), (9,1,1,0), (9,1,2,1), (9,1,2,0), (9,1,2,1), (9,1,2,0), (9,4,1,1), (9,4,1,0), (9,4,1,1), (9,4,1,0), (9,4,2,1), (9,4,2,0), (9,4,2,1), (9,4,2,0); select g,h,i,avg(x) as ax from olap_tmp_for_window_seq group by g,h,i; g | h | i | ax ---+---+---+------------------------ 9 | 4 | 1 | 0.50000000000000000000 9 | 4 | 2 | 0.50000000000000000000 9 | 1 | 2 | 0.50000000000000000000 9 | 1 | 1 | 0.50000000000000000000 (4 rows) -- begin equivalent select g, ax, avg(g) over (partition by h order by i), sum(ax) over (partition by i order by g) from (select g,h,i,avg(x) as ax from olap_tmp_for_window_seq group by g,h,i) rr; g | ax | avg | sum ---+------------------------+--------------------+------------------------ 9 | 0.50000000000000000000 | 9.0000000000000000 | 1.00000000000000000000 9 | 0.50000000000000000000 | 9.0000000000000000 | 1.00000000000000000000 9 | 0.50000000000000000000 | 9.0000000000000000 | 1.00000000000000000000 9 | 0.50000000000000000000 | 9.0000000000000000 | 1.00000000000000000000 (4 rows) select g, avg(x), avg(g) over (partition by h order by i), sum(avg(x)) over (partition by i order by g) from olap_tmp_for_window_seq group by g,h,i; g | avg | avg | sum ---+------------------------+--------------------+------------------------ 9 | 0.50000000000000000000 | 9.0000000000000000 | 1.00000000000000000000 9 | 0.50000000000000000000 | 9.0000000000000000 | 1.00000000000000000000 9 | 0.50000000000000000000 | 9.0000000000000000 | 1.00000000000000000000 9 | 0.50000000000000000000 | 9.0000000000000000 | 1.00000000000000000000 (4 rows) -- end equivalent drop table olap_tmp_for_window_seq; -- begin equivalent select g, cn, vn, pn, s, rank() over (partition by g order by s) from (select grouping(cn, vn, pn), cn, vn, pn, sum(qty*prc) from sale group by rollup(cn,vn,pn)) olap_tmp_for_window_seq(g,cn,vn,pn,s) order by 1,5; -- order 1,5 g | cn | vn | pn | s | rank ---+----+----+-----+---------+------ 0 | 1 | 30 | 300 | 0 | 1 0 | 1 | 50 | 400 | 0 | 1 0 | 1 | 20 | 100 | 0 | 1 0 | 1 | 10 | 200 | 0 | 1 0 | 2 | 50 | 400 | 0 | 1 0 | 3 | 40 | 200 | 0 | 1 0 | 4 | 40 | 700 | 1 | 7 0 | 4 | 40 | 800 | 1 | 7 0 | 3 | 30 | 600 | 60 | 9 0 | 3 | 30 | 500 | 60 | 9 0 | 1 | 30 | 500 | 60 | 9 0 | 2 | 40 | 100 | 2640000 | 12 1 | 2 | 50 | | 0 | 1 1 | 3 | 40 | | 0 | 1 1 | 1 | 10 | | 0 | 1 1 | 1 | 20 | | 0 | 1 1 | 1 | 50 | | 0 | 1 1 | 4 | 40 | | 2 | 6 1 | 1 | 30 | | 60 | 7 1 | 3 | 30 | | 120 | 8 1 | 2 | 40 | | 2640000 | 9 3 | 4 | | | 2 | 1 3 | 1 | | | 60 | 2 3 | 3 | | | 120 | 3 3 | 2 | | | 2640000 | 4 7 | | | | 2640182 | 1 (26 rows) select grouping(cn, vn, pn), cn, vn, pn, sum(qty*prc), rank() over (partition by grouping(cn,vn,pn) order by sum(qty*prc)) from sale group by rollup(cn,vn,pn) order by 1,5; -- order 1,5 grouping | cn | vn | pn | sum | rank ----------+----+----+-----+---------+------ 0 | 2 | 50 | 400 | 0 | 1 0 | 1 | 10 | 200 | 0 | 1 0 | 1 | 20 | 100 | 0 | 1 0 | 3 | 40 | 200 | 0 | 1 0 | 1 | 30 | 300 | 0 | 1 0 | 1 | 50 | 400 | 0 | 1 0 | 4 | 40 | 800 | 1 | 7 0 | 4 | 40 | 700 | 1 | 7 0 | 3 | 30 | 500 | 60 | 9 0 | 3 | 30 | 600 | 60 | 9 0 | 1 | 30 | 500 | 60 | 9 0 | 2 | 40 | 100 | 2640000 | 12 1 | 1 | 50 | | 0 | 1 1 | 2 | 50 | | 0 | 1 1 | 1 | 10 | | 0 | 1 1 | 1 | 20 | | 0 | 1 1 | 3 | 40 | | 0 | 1 1 | 4 | 40 | | 2 | 6 1 | 1 | 30 | | 60 | 7 1 | 3 | 30 | | 120 | 8 1 | 2 | 40 | | 2640000 | 9 3 | 4 | | | 2 | 1 3 | 1 | | | 60 | 2 3 | 3 | | | 120 | 3 3 | 2 | | | 2640000 | 4 7 | | | | 2640182 | 1 (26 rows) -- end equivalent -- basic framed query test select pn, count(*) over (order by pn range between 1 preceding and 1 following) as c from sale order by pn; pn | c -----+--- 100 | 2 100 | 2 200 | 2 200 | 2 300 | 1 400 | 2 400 | 2 500 | 2 500 | 2 600 | 1 700 | 1 800 | 1 (12 rows) -- Some data types, like date, when mixed with operators like "-" result in -- data returned in a different data type. We're smart enough to detect -- this but some tests are good. select cn, dt, qty, sum(qty) over (order by dt range between '1 year'::interval preceding and '1 month'::interval following) from sale; --mvd 2->4 cn | dt | qty | sum ----+------------+------+------ 2 | 01-01-1401 | 1100 | 1100 1 | 03-01-1401 | 1 | 1102 3 | 04-01-1401 | 1 | 1103 1 | 05-01-1401 | 1 | 1144 1 | 05-02-1401 | 1 | 1144 4 | 06-01-1401 | 1 | 1144 1 | 06-01-1401 | 12 | 1144 1 | 06-01-1401 | 1 | 1144 3 | 06-01-1401 | 12 | 1144 3 | 06-01-1401 | 12 | 1144 2 | 06-01-1401 | 1 | 1144 4 | 06-01-1401 | 1 | 1144 (12 rows) select cn, dt, qty, prc, sum(qty) over (order by prc range '314.15926535'::float8 preceding) as sum from sale; --mvd 4->5 cn | dt | qty | prc | sum ----+------------+------+------+------ 3 | 04-01-1401 | 1 | 0 | 6 1 | 05-01-1401 | 1 | 0 | 6 2 | 06-01-1401 | 1 | 0 | 6 1 | 03-01-1401 | 1 | 0 | 6 1 | 05-02-1401 | 1 | 0 | 6 1 | 06-01-1401 | 1 | 0 | 6 4 | 06-01-1401 | 1 | 1 | 8 4 | 06-01-1401 | 1 | 1 | 8 3 | 06-01-1401 | 12 | 5 | 44 1 | 06-01-1401 | 12 | 5 | 44 3 | 06-01-1401 | 12 | 5 | 44 2 | 01-01-1401 | 1100 | 2400 | 1100 (12 rows) -- There are some types we cannot cast back, test for those too select cn, dt, qty, sum(qty) over (order by dt range '2007-08-05'::date preceding) as sum from sale; --mvd 2->4 ERROR: invalid RANGE parameter HINT: Operations between window specification the ORDER BY column and RANGE parameter must result in a data type which can be cast back to the ORDER BY column type select cn, dt, qty, sum(qty) over (order by dt range '192.168.1.1'::inet preceding) as sum from sale; --mvd 2->4 ERROR: window specification RANGE parameter type must be coercible to ORDER BY column type -- Test for FOLLOWING frames select cn, prc, dt, sum(prc) over (order by ord,dt,cn rows between 2 following and 3 following) as f from sale_ord; cn | prc | dt | f ----+------+------------+---- 2 | 2400 | 01-01-1401 | 0 1 | 0 | 03-01-1401 | 0 3 | 0 | 04-01-1401 | 0 1 | 0 | 05-01-1401 | 0 1 | 0 | 05-02-1401 | 5 1 | 0 | 06-01-1401 | 10 2 | 0 | 06-01-1401 | 10 1 | 5 | 06-01-1401 | 6 3 | 5 | 06-01-1401 | 2 3 | 5 | 06-01-1401 | 1 4 | 1 | 06-01-1401 | 4 | 1 | 06-01-1401 | (12 rows) -- Check that mixing cume_dist() with other window functions on the same -- window does not result in badness select cn, rank() over (w), cume_dist() over (w) from customer window w as (order by cname); cn | rank | cume_dist ----+------+----------- 2 | 1 | 0.25 3 | 2 | 0.5 1 | 3 | 0.75 4 | 4 | 1 (4 rows) -- Test for MPP-1762 -- begin equivalent SELECT sale.prc,sale.cn, sale.cn, AVG(sale.pn) OVER(order by sale.pn desc,sale.vn asc,sale.cn desc rows between unbounded preceding and unbounded following) as avg, sale.vn,sale.pn, DENSE_RANK() OVER(order by sale.pn asc) FROM sale,vendor WHERE sale.vn =vendor.vn; prc | cn | cn | avg | vn | pn | dense_rank ------+----+----+----------------------+----+-----+------------ 1 | 4 | 4 | 400.0000000000000000 | 40 | 800 | 8 1 | 4 | 4 | 400.0000000000000000 | 40 | 700 | 7 5 | 3 | 3 | 400.0000000000000000 | 30 | 600 | 6 5 | 3 | 3 | 400.0000000000000000 | 30 | 500 | 5 5 | 1 | 1 | 400.0000000000000000 | 30 | 500 | 5 0 | 2 | 2 | 400.0000000000000000 | 50 | 400 | 4 0 | 1 | 1 | 400.0000000000000000 | 50 | 400 | 4 0 | 1 | 1 | 400.0000000000000000 | 30 | 300 | 3 0 | 1 | 1 | 400.0000000000000000 | 10 | 200 | 2 0 | 3 | 3 | 400.0000000000000000 | 40 | 200 | 2 0 | 1 | 1 | 400.0000000000000000 | 20 | 100 | 1 2400 | 2 | 2 | 400.0000000000000000 | 40 | 100 | 1 (12 rows) SELECT sale.prc,sale.cn,sale.cn, AVG(sale.pn) OVER(win1), sale.vn,sale.pn, DENSE_RANK() OVER(win2) FROM sale,vendor WHERE sale.vn=vendor.vn WINDOW win1 as (order by sale.pn desc,sale.vn asc,sale.cn desc rows between unbounded preceding and unbounded following ), win2 as (order by sale.pn asc); prc | cn | cn | avg | vn | pn | dense_rank ------+----+----+----------------------+----+-----+------------ 1 | 4 | 4 | 400.0000000000000000 | 40 | 800 | 8 1 | 4 | 4 | 400.0000000000000000 | 40 | 700 | 7 5 | 3 | 3 | 400.0000000000000000 | 30 | 600 | 6 5 | 3 | 3 | 400.0000000000000000 | 30 | 500 | 5 5 | 1 | 1 | 400.0000000000000000 | 30 | 500 | 5 0 | 2 | 2 | 400.0000000000000000 | 50 | 400 | 4 0 | 1 | 1 | 400.0000000000000000 | 50 | 400 | 4 0 | 1 | 1 | 400.0000000000000000 | 30 | 300 | 3 0 | 1 | 1 | 400.0000000000000000 | 10 | 200 | 2 0 | 3 | 3 | 400.0000000000000000 | 40 | 200 | 2 0 | 1 | 1 | 400.0000000000000000 | 20 | 100 | 1 2400 | 2 | 2 | 400.0000000000000000 | 40 | 100 | 1 (12 rows) -- end equivalent -- Test for MPP-1756, the planner should create just the one key level explain select cn, sum(qty) over (order by ord,cn rows between 1 preceding and 1 following), sum(qty) over (order by ord,cn rows between 1 preceding and 1 following) from sale_ord; QUERY PLAN --------------------------------------------------------------------------- WindowAgg (cost=2.34..2.67 rows=12 width=12) Order By: ord, cn -> Gather Motion 3:1 (slice1; segments: 3) (cost=2.34..2.61 rows=12 width=12) Merge Key: ord, cn -> Sort (cost=2.34..2.37 rows=6 width=12) Sort Key: ord, cn -> Seq Scan on sale_ord (cost=0.00..2.12 rows=6 width=12) (8 rows) select cn, sum(qty) over (order by ord,cn rows between 1 preceding and 1 following), sum(qty) over (order by ord,cn rows between 1 preceding and 1 following) from sale_ord; cn | sum | sum ----+------+------ 2 | 1101 | 1101 1 | 1102 | 1102 3 | 3 | 3 1 | 3 | 3 1 | 3 | 3 1 | 3 | 3 2 | 14 | 14 1 | 25 | 25 3 | 36 | 36 3 | 25 | 25 4 | 14 | 14 4 | 2 | 2 (12 rows) -- test for MPP-1760. Framed queries without order by clauses are not -- permitted. select cn, sum(count(*)) over (range between 1 preceding and 1 following) from sale group by cn; ERROR: window specifications with a framing clause must have an ORDER BY clause LINE 2: sum(count(*)) over (range between 1 preceding and 1 followin... ^ -- test for issue which reopened MPP-1762 -- We allow the user to specify DESC sort order SELECT sale.cn,sale.vn,AVG(cast (sale.vn as int)) OVER(order by ord desc,sale.cn desc) as avg from sale_ord as sale; cn | vn | avg ----+----+--------------------- 4 | 40 | 40.0000000000000000 4 | 40 | 40.0000000000000000 3 | 30 | 36.6666666666666667 3 | 30 | 35.0000000000000000 1 | 30 | 34.0000000000000000 2 | 50 | 36.6666666666666667 1 | 50 | 38.5714285714285714 1 | 30 | 37.5000000000000000 1 | 20 | 35.5555555555555556 3 | 40 | 36.0000000000000000 1 | 10 | 33.6363636363636364 2 | 40 | 34.1666666666666667 (12 rows) -- a bit harder SELECT sale.cn,sale.dt, sale.vn,AVG(cast (sale.vn as int)) OVER(order by sale.cn desc, sale.dt asc) as avg from sale;--mvd 1,2->4 cn | dt | vn | avg ----+------------+----+--------------------- 4 | 06-01-1401 | 40 | 40.0000000000000000 4 | 06-01-1401 | 40 | 40.0000000000000000 3 | 04-01-1401 | 40 | 40.0000000000000000 3 | 06-01-1401 | 30 | 36.0000000000000000 3 | 06-01-1401 | 30 | 36.0000000000000000 2 | 01-01-1401 | 40 | 36.6666666666666667 2 | 06-01-1401 | 50 | 38.5714285714285714 1 | 03-01-1401 | 10 | 35.0000000000000000 1 | 05-01-1401 | 20 | 33.3333333333333333 1 | 05-02-1401 | 30 | 33.0000000000000000 1 | 06-01-1401 | 30 | 34.1666666666666667 1 | 06-01-1401 | 50 | 34.1666666666666667 (12 rows) -- Even harder (MPP-1805) SELECT sale.cn,sale.prc,sale.qty, SUM(floor(sale.prc*sale.qty)) OVER(order by sale.cn desc range between 4 preceding and 4 following) as foo FROM sale; --mvd 1->4 cn | prc | qty | foo ----+------+------+--------- 4 | 1 | 1 | 2640182 4 | 1 | 1 | 2640182 3 | 5 | 12 | 2640182 3 | 0 | 1 | 2640182 3 | 5 | 12 | 2640182 2 | 0 | 1 | 2640182 2 | 2400 | 1100 | 2640182 1 | 0 | 1 | 2640182 1 | 0 | 1 | 2640182 1 | 5 | 12 | 2640182 1 | 0 | 1 | 2640182 1 | 0 | 1 | 2640182 (12 rows) SELECT sale.pn,sale.vn, SUM(cast (sale.vn as int)) OVER(order by sale.cn desc range current row) as sum, sale.cn from sale; --mvd 4->3 pn | vn | sum | cn -----+----+-----+---- 800 | 40 | 80 | 4 700 | 40 | 80 | 4 500 | 30 | 100 | 3 200 | 40 | 100 | 3 600 | 30 | 100 | 3 400 | 50 | 90 | 2 100 | 40 | 90 | 2 400 | 50 | 140 | 1 300 | 30 | 140 | 1 500 | 30 | 140 | 1 200 | 10 | 140 | 1 100 | 20 | 140 | 1 (12 rows) -- test for MPP-1810 and other similar queries SELECT sale.vn,sale.vn,sale.qty, FIRST_VALUE(floor(sale.vn)) OVER(order by sale.vn asc range 0 preceding) as f from sale; --mvd 1->4 vn | vn | qty | f ----+----+------+---- 10 | 10 | 1 | 10 20 | 20 | 1 | 20 30 | 30 | 12 | 30 30 | 30 | 12 | 30 30 | 30 | 1 | 30 30 | 30 | 12 | 30 40 | 40 | 1 | 40 40 | 40 | 1100 | 40 40 | 40 | 1 | 40 40 | 40 | 1 | 40 50 | 50 | 1 | 50 50 | 50 | 1 | 50 (12 rows) select cn, cast(cname as varchar(10)), first_value(cast(cname as varchar(10))) over(order by cn range 2 preceding) as f from customer; cn | cname | f ----+------------+--------- 1 | Macbeth | Macbeth 2 | Duncan | Macbeth 3 | Lady Macbe | Macbeth 4 | Witches, I | Duncan (4 rows) select cn, prc, dt, first_value(prc) over (order by ord,dt rows between 1 following and 4 following) as f from sale_ord; cn | prc | dt | f ----+------+------------+--- 2 | 2400 | 01-01-1401 | 0 1 | 0 | 03-01-1401 | 0 3 | 0 | 04-01-1401 | 0 1 | 0 | 05-01-1401 | 0 1 | 0 | 05-02-1401 | 0 1 | 0 | 06-01-1401 | 0 2 | 0 | 06-01-1401 | 5 1 | 5 | 06-01-1401 | 5 3 | 5 | 06-01-1401 | 5 3 | 5 | 06-01-1401 | 1 4 | 1 | 06-01-1401 | 1 4 | 1 | 06-01-1401 | (12 rows) -- test for second issue in MPP-1810 select vn, first_value(vn) over(order by vn range 2 preceding) from vendor; vn | first_value ----+------------- 10 | 10 20 | 20 30 | 30 40 | 40 50 | 50 (5 rows) -- MPP-1819 SELECT sale.cn,sale.pn, FIRST_VALUE(sale.pn+sale.pn) OVER(order by ord,sale.cn rows unbounded preceding) as fv from sale_ord as sale; cn | pn | fv ----+-----+----- 2 | 100 | 200 1 | 200 | 200 3 | 200 | 200 1 | 100 | 200 1 | 300 | 200 1 | 400 | 200 2 | 400 | 200 1 | 500 | 200 3 | 500 | 200 3 | 600 | 200 4 | 700 | 200 4 | 800 | 200 (12 rows) SELECT sale.cn,sale.pn, FIRST_VALUE(((cn*100 + (sale.pn+sale.pn)%100)/100)) OVER(order by sale.cn range unbounded preceding) as fv from sale; --mvd 1->3 cn | pn | fv ----+-----+---- 1 | 100 | 1 1 | 200 | 1 1 | 400 | 1 1 | 300 | 1 1 | 500 | 1 2 | 100 | 1 2 | 400 | 1 3 | 600 | 1 3 | 200 | 1 3 | 500 | 1 4 | 700 | 1 4 | 800 | 1 (12 rows) -- MPP-1812 SELECT sale.cn,sale.prc,sale.vn, SUM(floor(sale.prc*sale.vn)) OVER(order by sale.cn asc,sale.prc range current row) as fv from sale; --mvd 1,2->4 cn | prc | vn | fv ----+------+----+------- 1 | 0 | 20 | 0 1 | 0 | 10 | 0 1 | 0 | 50 | 0 1 | 0 | 30 | 0 1 | 5 | 30 | 150 2 | 0 | 50 | 0 2 | 2400 | 40 | 96000 3 | 0 | 40 | 0 3 | 5 | 30 | 300 3 | 5 | 30 | 300 4 | 1 | 40 | 80 4 | 1 | 40 | 80 (12 rows) -- MPP-1843, check the interaction between ROWS frames and partitioning SELECT sale.dt,sale.prc,sale.cn, sale.vn, SUM(sale.cn) OVER(partition by sale.dt,sale.prc order by sale.cn asc rows between 0 following and 1 following) as sum from sale order by dt, prc, cn; --mvd 1,2->5 dt | prc | cn | vn | sum ------------+------+----+----+----- 01-01-1401 | 2400 | 2 | 40 | 2 03-01-1401 | 0 | 1 | 10 | 1 04-01-1401 | 0 | 3 | 40 | 3 05-01-1401 | 0 | 1 | 20 | 1 05-02-1401 | 0 | 1 | 30 | 1 06-01-1401 | 0 | 1 | 50 | 3 06-01-1401 | 0 | 2 | 50 | 2 06-01-1401 | 1 | 4 | 40 | 4 06-01-1401 | 1 | 4 | 40 | 8 06-01-1401 | 5 | 1 | 30 | 4 06-01-1401 | 5 | 3 | 30 | 6 06-01-1401 | 5 | 3 | 30 | 3 (12 rows) -- MPP-1804, Used to return incorrect number of rows SELECT sale.vn,sale.cn, SUM(sale.cn) OVER(partition by sale.vn order by sale.cn desc range between current row and unbounded following) as sum from sale; --mvd 1->3 vn | cn | sum ----+----+----- 10 | 1 | 1 20 | 1 | 1 30 | 3 | 8 30 | 3 | 8 30 | 1 | 2 30 | 1 | 2 40 | 4 | 13 40 | 4 | 13 40 | 3 | 5 40 | 2 | 2 50 | 2 | 3 50 | 1 | 1 (12 rows) -- MPP-1840, grouping + windowing --begin_equivalent SELECT cn, vn, pn, GROUPING(cn,vn,pn), SUM(vn) OVER (PARTITION BY GROUPING(cn,vn,pn) ORDER BY cn) as sum FROM sale GROUP BY ROLLUP(cn,vn,pn) order by 4; -- order 4 cn | vn | pn | grouping | sum ----+----+-----+----------+----- 1 | 20 | 100 | 0 | 140 1 | 50 | 400 | 0 | 140 1 | 30 | 500 | 0 | 140 1 | 30 | 300 | 0 | 140 2 | 50 | 400 | 0 | 230 2 | 40 | 100 | 0 | 230 3 | 40 | 200 | 0 | 330 3 | 30 | 500 | 0 | 330 3 | 30 | 600 | 0 | 330 4 | 40 | 700 | 0 | 410 4 | 40 | 800 | 0 | 410 1 | 10 | 200 | 0 | 140 1 | 20 | | 1 | 110 1 | 10 | | 1 | 110 1 | 50 | | 1 | 110 2 | 50 | | 1 | 200 2 | 40 | | 1 | 200 3 | 40 | | 1 | 270 3 | 30 | | 1 | 270 4 | 40 | | 1 | 310 1 | 30 | | 1 | 110 2 | | | 3 | 3 | | | 3 | 4 | | | 3 | 1 | | | 3 | | | | 7 | (26 rows) select cn,vn,pn,grouping, sum(vn) over (partition by grouping order by cn) as sum from (select cn,vn,pn,grouping(cn,vn,pn) from sale group by rollup(cn,vn,pn)) t order by 4; -- order 4 cn | vn | pn | grouping | sum ----+----+-----+----------+----- 1 | 20 | 100 | 0 | 140 1 | 50 | 400 | 0 | 140 1 | 30 | 500 | 0 | 140 1 | 30 | 300 | 0 | 140 2 | 50 | 400 | 0 | 230 2 | 40 | 100 | 0 | 230 3 | 40 | 200 | 0 | 330 3 | 30 | 500 | 0 | 330 3 | 30 | 600 | 0 | 330 4 | 40 | 700 | 0 | 410 4 | 40 | 800 | 0 | 410 1 | 10 | 200 | 0 | 140 1 | 20 | | 1 | 110 1 | 10 | | 1 | 110 1 | 50 | | 1 | 110 2 | 50 | | 1 | 200 2 | 40 | | 1 | 200 3 | 40 | | 1 | 270 3 | 30 | | 1 | 270 4 | 40 | | 1 | 310 1 | 30 | | 1 | 110 2 | | | 3 | 3 | | | 3 | 4 | | | 3 | 1 | | | 3 | | | | 7 | (26 rows) --end_equivalent -- MPP-1860 SELECT sale.pn,sale.vn,sale.qty, SUM(floor(sale.vn*sale.qty)) OVER(order by ord,sale.pn asc rows between 4 preceding and 0 preceding) as sum FROM sale_ord as sale; pn | vn | qty | sum -----+----+------+------- 100 | 40 | 1100 | 44000 200 | 10 | 1 | 44010 200 | 40 | 1 | 44050 100 | 20 | 1 | 44070 300 | 30 | 1 | 44100 400 | 50 | 1 | 150 400 | 50 | 1 | 190 500 | 30 | 12 | 510 500 | 30 | 12 | 850 600 | 30 | 12 | 1180 700 | 40 | 1 | 1170 800 | 40 | 1 | 1160 (12 rows) -- MPP-1866 SELECT sale.cn,sale.pn,sale.prc, SUM(floor(sale.pn*sale.prc)) OVER(order by sale.cn asc, pn rows between current row and unbounded following ) as sum FROM sale; cn | pn | prc | sum ----+-----+------+-------- 1 | 100 | 0 | 249500 1 | 200 | 0 | 249500 1 | 300 | 0 | 249500 1 | 400 | 0 | 249500 1 | 500 | 5 | 249500 2 | 100 | 2400 | 247000 2 | 400 | 0 | 7000 3 | 200 | 0 | 7000 3 | 500 | 5 | 7000 3 | 600 | 5 | 4500 4 | 700 | 1 | 1500 4 | 800 | 1 | 800 (12 rows) SELECT sale.pn,sale.vn, COUNT(floor(sale.vn)) OVER(order by ord,sale.pn asc rows between current row and unbounded following) FROM sale_ord as sale; pn | vn | count -----+----+------- 100 | 40 | 12 200 | 10 | 11 200 | 40 | 10 100 | 20 | 9 300 | 30 | 8 400 | 50 | 7 400 | 50 | 6 500 | 30 | 5 500 | 30 | 4 600 | 30 | 3 700 | 40 | 2 800 | 40 | 1 (12 rows) -- Sanity test for executor detection of non-sense frames SELECT sale.pn,sale.cn,sale.prc, AVG(cast (sale.prc as int)) OVER(order by sale.cn asc range between 6 following and 0 following ) as c FROM sale; --mvd 2->4 pn | cn | prc | c -----+----+------+--- 100 | 1 | 0 | 200 | 1 | 0 | 400 | 1 | 0 | 300 | 1 | 0 | 500 | 1 | 5 | 100 | 2 | 2400 | 400 | 2 | 0 | 600 | 3 | 5 | 200 | 3 | 0 | 500 | 3 | 5 | 700 | 4 | 1 | 800 | 4 | 1 | (12 rows) SELECT sale.pn,sale.cn,sale.prc, AVG(cast (sale.prc as int)) OVER(order by ord,sale.cn asc rows between 6 following and 0 following ) as c FROM sale_ord as sale; pn | cn | prc | c -----+----+------+--- 100 | 2 | 2400 | 200 | 1 | 0 | 200 | 3 | 0 | 100 | 1 | 0 | 300 | 1 | 0 | 400 | 1 | 0 | 400 | 2 | 0 | 500 | 1 | 5 | 500 | 3 | 5 | 600 | 3 | 5 | 700 | 4 | 1 | 800 | 4 | 1 | (12 rows) SELECT sale.pn,sale.cn,sale.prc, AVG(cast (sale.prc as int)) OVER(order by sale.cn asc range between 1 preceding and 10 preceding ) as c FROM sale; --mvd 2->4 pn | cn | prc | c -----+----+------+--- 100 | 1 | 0 | 200 | 1 | 0 | 400 | 1 | 0 | 300 | 1 | 0 | 500 | 1 | 5 | 100 | 2 | 2400 | 400 | 2 | 0 | 600 | 3 | 5 | 200 | 3 | 0 | 500 | 3 | 5 | 700 | 4 | 1 | 800 | 4 | 1 | (12 rows) -- Check LEAD() -- sanity tests select lead(cn) from sale; ERROR: window function lead requires an OVER clause LINE 1: select lead(cn) from sale; ^ select cn, cname, lead(cname, -1) over (order by cn) from customer; cn | cname | lead ----+--------------+-------------- 1 | Macbeth | 2 | Duncan | Macbeth 3 | Lady Macbeth | Duncan 4 | Witches, Inc | Lady Macbeth (4 rows) -- actual LEAD tests select cn, cname, lead(cname, 2, 'undefined') over (order by cn) from customer; cn | cname | lead ----+--------------+-------------- 1 | Macbeth | Lady Macbeth 2 | Duncan | Witches, Inc 3 | Lady Macbeth | undefined 4 | Witches, Inc | undefined (4 rows) select cn, cname, lead(cname, 2) over (order by cn) from customer; cn | cname | lead ----+--------------+-------------- 1 | Macbeth | Lady Macbeth 2 | Duncan | Witches, Inc 3 | Lady Macbeth | 4 | Witches, Inc | (4 rows) select cn, cname, lead(cname) over (order by cn) from customer; cn | cname | lead ----+--------------+-------------- 1 | Macbeth | Duncan 2 | Duncan | Lady Macbeth 3 | Lady Macbeth | Witches, Inc 4 | Witches, Inc | (4 rows) select cn, vn, pn, lead(cn, 1, cn + 1) over (order by cn, vn, pn) from sale order by 1, 2, 3; cn | vn | pn | lead ----+----+-----+------ 1 | 10 | 200 | 1 1 | 20 | 100 | 1 1 | 30 | 300 | 1 1 | 30 | 500 | 1 1 | 50 | 400 | 2 2 | 40 | 100 | 2 2 | 50 | 400 | 3 3 | 30 | 500 | 3 3 | 30 | 600 | 3 3 | 40 | 200 | 4 4 | 40 | 700 | 4 4 | 40 | 800 | 5 (12 rows) select cn, vn, pn, qty * prc, lead(qty * prc) over (order by cn, vn, pn) from sale order by 1, 2, 3; cn | vn | pn | ?column? | lead ----+----+-----+----------+--------- 1 | 10 | 200 | 0 | 0 1 | 20 | 100 | 0 | 0 1 | 30 | 300 | 0 | 60 1 | 30 | 500 | 60 | 0 1 | 50 | 400 | 0 | 2640000 2 | 40 | 100 | 2640000 | 0 2 | 50 | 400 | 0 | 60 3 | 30 | 500 | 60 | 60 3 | 30 | 600 | 60 | 0 3 | 40 | 200 | 0 | 1 4 | 40 | 700 | 1 | 1 4 | 40 | 800 | 1 | (12 rows) -- Check LAG() -- actual LAG tests select cn, cname, lag(cname, 2, 'undefined') over (order by cn) from customer; cn | cname | lag ----+--------------+----------- 1 | Macbeth | undefined 2 | Duncan | undefined 3 | Lady Macbeth | Macbeth 4 | Witches, Inc | Duncan (4 rows) select cn, cname, lag(cname, 2) over (order by cn) from customer; cn | cname | lag ----+--------------+--------- 1 | Macbeth | 2 | Duncan | 3 | Lady Macbeth | Macbeth 4 | Witches, Inc | Duncan (4 rows) select cn, cname, lag(cname) over (order by cn) from customer; cn | cname | lag ----+--------------+-------------- 1 | Macbeth | 2 | Duncan | Macbeth 3 | Lady Macbeth | Duncan 4 | Witches, Inc | Lady Macbeth (4 rows) select cn, vn, pn, lag(cn, 1, cn + 1) over (order by cn, vn, pn) from sale order by 1, 2, 3; cn | vn | pn | lag ----+----+-----+----- 1 | 10 | 200 | 2 1 | 20 | 100 | 1 1 | 30 | 300 | 1 1 | 30 | 500 | 1 1 | 50 | 400 | 1 2 | 40 | 100 | 1 2 | 50 | 400 | 2 3 | 30 | 500 | 2 3 | 30 | 600 | 3 3 | 40 | 200 | 3 4 | 40 | 700 | 3 4 | 40 | 800 | 4 (12 rows) select cn, vn, pn, qty * prc, lag(qty * prc) over (order by cn, vn, pn) from sale order by 1, 2, 3; cn | vn | pn | ?column? | lag ----+----+-----+----------+--------- 1 | 10 | 200 | 0 | 1 | 20 | 100 | 0 | 0 1 | 30 | 300 | 0 | 0 1 | 30 | 500 | 60 | 0 1 | 50 | 400 | 0 | 60 2 | 40 | 100 | 2640000 | 0 2 | 50 | 400 | 0 | 2640000 3 | 30 | 500 | 60 | 0 3 | 30 | 600 | 60 | 60 3 | 40 | 200 | 0 | 60 4 | 40 | 700 | 1 | 0 4 | 40 | 800 | 1 | 1 (12 rows) -- LAST_VALUE tests SELECT sale.cn,sale.qty,sale.pn, LAST_VALUE(sale.qty*sale.pn) OVER(partition by sale.cn order by sale.cn,pn range between unbounded preceding and unbounded following ) as lv from sale order by 1, 2, 3; --mvd 1->4 cn | qty | pn | lv ----+------+-----+------ 1 | 1 | 100 | 6000 1 | 1 | 200 | 6000 1 | 1 | 300 | 6000 1 | 1 | 400 | 6000 1 | 12 | 500 | 6000 2 | 1 | 400 | 400 2 | 1100 | 100 | 400 3 | 1 | 200 | 7200 3 | 12 | 500 | 7200 3 | 12 | 600 | 7200 4 | 1 | 700 | 800 4 | 1 | 800 | 800 (12 rows) SELECT sale.vn,sale.qty, LAST_VALUE(floor(sale.vn)) OVER(order by sale.vn asc range 0 preceding) as f from sale; --mvd 1->3 vn | qty | f ----+------+---- 10 | 1 | 10 20 | 1 | 20 30 | 12 | 30 30 | 12 | 30 30 | 1 | 30 30 | 12 | 30 40 | 1 | 40 40 | 1100 | 40 40 | 1 | 40 40 | 1 | 40 50 | 1 | 50 50 | 1 | 50 (12 rows) select cn, cast(cname as varchar(10)), last_value(cast(cname as varchar(10))) over(order by cn range 2 preceding) as f from customer; cn | cname | f ----+------------+------------ 1 | Macbeth | Macbeth 2 | Duncan | Duncan 3 | Lady Macbe | Lady Macbe 4 | Witches, I | Witches, I (4 rows) select cn, prc, dt, last_value(prc) over (order by dt, prc, cn rows between 1 following and 4 following) as f from sale; cn | prc | dt | f ----+------+------------+--- 2 | 2400 | 01-01-1401 | 0 1 | 0 | 03-01-1401 | 0 3 | 0 | 04-01-1401 | 0 1 | 0 | 05-01-1401 | 1 1 | 0 | 05-02-1401 | 1 1 | 0 | 06-01-1401 | 5 2 | 0 | 06-01-1401 | 5 4 | 1 | 06-01-1401 | 5 4 | 1 | 06-01-1401 | 5 1 | 5 | 06-01-1401 | 5 3 | 5 | 06-01-1401 | 5 3 | 5 | 06-01-1401 | (12 rows) select vn, last_value(vn) over(order by vn range between 2 preceding and 2 following) from vendor; vn | last_value ----+------------ 10 | 10 20 | 20 30 | 30 40 | 40 50 | 50 (5 rows) select vn, last_value(vn) over(order by vn range between 20 preceding and 20 following) from vendor; vn | last_value ----+------------ 10 | 30 20 | 40 30 | 50 40 | 50 50 | 50 (5 rows) SELECT sale.cn,sale.pn, last_VALUE(sale.pn+sale.pn) OVER(order by ord,sale.cn rows between current row and unbounded following) as fv from sale_ord as sale; cn | pn | fv ----+-----+------ 2 | 100 | 1600 1 | 200 | 1600 3 | 200 | 1600 1 | 100 | 1600 1 | 300 | 1600 1 | 400 | 1600 2 | 400 | 1600 1 | 500 | 1600 3 | 500 | 1600 3 | 600 | 1600 4 | 700 | 1600 4 | 800 | 1600 (12 rows) SELECT sale.cn,sale.pn, last_VALUE(((cn*100 + (sale.pn+sale.pn)/100)%100)) OVER(order by sale.cn, sale.pn range between current row and unbounded following) as fv from sale; --mvd 1,2->3 cn | pn | fv ----+-----+---- 1 | 100 | 16 1 | 200 | 16 1 | 300 | 16 1 | 400 | 16 1 | 500 | 16 2 | 100 | 16 2 | 400 | 16 3 | 200 | 16 3 | 500 | 16 3 | 600 | 16 4 | 700 | 16 4 | 800 | 16 (12 rows) -- Test obscure types create table typetest_for_window_seq (i int[], j box, k bit, l bytea, m text[]); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into typetest_for_window_seq values('{1, 2, 3}', '(1, 2), (3, 4)', '1', E'\012\001', '{foo, bar}'); insert into typetest_for_window_seq values('{4, 5, 6}', '(3, 4), (6, 7)', '0', E'\002', '{bar, baz}'); select i, lead(i, 1, '{1}') over (w), lead(j, 1, '(0, 0), (1, 1)') over (w), lead(k, 1) over(w), lead(l, 1, E'\015') over (w), lead(m, 1, '{test}') over (w) from typetest_for_window_seq window w as (order by i); i | lead | lead | lead | lead | lead ---------+---------+-------------+------+------+----------- {1,2,3} | {4,5,6} | (6,7),(3,4) | 0 | \x02 | {bar,baz} {4,5,6} | {1} | (1,1),(0,0) | | \x0d | {test} (2 rows) select i, lag(i, 1, '{1}') over (w), lag(j, 1, '(0, 0), (1, 1)') over (w), lag(k, 1) over(w), lag(l, 1, E'\015') over (w), lag(m, 1, '{test}') over (w) from typetest_for_window_seq window w as (order by i); i | lag | lag | lag | lag | lag ---------+---------+-------------+-----+--------+----------- {1,2,3} | {1} | (1,1),(0,0) | | \x0d | {test} {4,5,6} | {1,2,3} | (3,4),(1,2) | 1 | \x0a01 | {foo,bar} (2 rows) select i, first_value(i) over (w), first_value(j) over (w), first_value(k) over(w), first_value(l) over (w), first_value(m) over (w) from typetest_for_window_seq window w as (order by i rows 1 preceding); i | first_value | first_value | first_value | first_value | first_value ---------+-------------+-------------+-------------+-------------+------------- {1,2,3} | {1,2,3} | (3,4),(1,2) | 1 | \x0a01 | {foo,bar} {4,5,6} | {1,2,3} | (3,4),(1,2) | 1 | \x0a01 | {foo,bar} (2 rows) select i, last_value(i) over (w), last_value(j) over (w), last_value(k) over(w), last_value(l) over (w), last_value(m) over (w) from typetest_for_window_seq window w as (order by i rows between current row and 1 following); i | last_value | last_value | last_value | last_value | last_value ---------+------------+-------------+------------+------------+------------ {1,2,3} | {4,5,6} | (6,7),(3,4) | 0 | \x02 | {bar,baz} {4,5,6} | {4,5,6} | (6,7),(3,4) | 0 | \x02 | {bar,baz} (2 rows) drop table typetest_for_window_seq; -- MPP-1881 SELECT sale.pn, COUNT(pn) OVER(order by sale.pn asc range between unbounded preceding and unbounded following) FROM sale; pn | count -----+------- 100 | 12 100 | 12 200 | 12 200 | 12 300 | 12 400 | 12 400 | 12 500 | 12 500 | 12 600 | 12 700 | 12 800 | 12 (12 rows) -- MPP-1878 SELECT sale.vn,sale.cn, COUNT(vn) OVER(order by sale.cn asc range between unbounded preceding and 2 following) FROM sale; --mvd 2->3 vn | cn | count ----+----+------- 20 | 1 | 10 10 | 1 | 10 50 | 1 | 10 30 | 1 | 10 30 | 1 | 10 40 | 2 | 12 50 | 2 | 12 30 | 3 | 12 40 | 3 | 12 30 | 3 | 12 40 | 4 | 12 40 | 4 | 12 (12 rows) -- MPP-1877 SELECT sale.vn,sale.cn, COUNT(vn) OVER(order by sale.cn asc range between unbounded preceding and 2 preceding) FROM sale; --mvd 2->3 vn | cn | count ----+----+------- 20 | 1 | 0 10 | 1 | 0 50 | 1 | 0 30 | 1 | 0 30 | 1 | 0 40 | 2 | 0 50 | 2 | 0 30 | 3 | 5 40 | 3 | 5 30 | 3 | 5 40 | 4 | 7 40 | 4 | 7 (12 rows) SELECT sale.vn,sale.cn, COUNT(vn) OVER(order by ord,sale.cn asc rows between unbounded preceding and 2 preceding) FROM sale_ord as sale; vn | cn | count ----+----+------- 40 | 2 | 0 10 | 1 | 0 40 | 3 | 1 20 | 1 | 2 30 | 1 | 3 50 | 1 | 4 50 | 2 | 5 30 | 1 | 6 30 | 3 | 7 30 | 3 | 8 40 | 4 | 9 40 | 4 | 10 (12 rows) -- Framing clauses select cn,count(*) over (order by cn rows between 2 preceding and 1 preceding) as c from sale; cn | c ----+--- 1 | 0 1 | 1 1 | 2 1 | 2 1 | 2 2 | 2 2 | 2 3 | 2 3 | 2 3 | 2 4 | 2 4 | 2 (12 rows) select cn,count(*) over (order by cn rows between 2 preceding and 0 preceding) as c from sale; cn | c ----+--- 1 | 1 1 | 2 1 | 3 1 | 3 1 | 3 2 | 3 2 | 3 3 | 3 3 | 3 3 | 3 4 | 3 4 | 3 (12 rows) select cn,count(*) over (order by cn rows between 2 preceding and 1 following) as c from sale; cn | c ----+--- 1 | 2 1 | 3 1 | 4 1 | 4 1 | 4 2 | 4 2 | 4 3 | 4 3 | 4 3 | 4 4 | 4 4 | 3 (12 rows) select cn,count(*) over (order by cn rows between 0 preceding and 1 following) as c from sale; cn | c ----+--- 1 | 2 1 | 2 1 | 2 1 | 2 1 | 2 2 | 2 2 | 2 3 | 2 3 | 2 3 | 2 4 | 2 4 | 1 (12 rows) select cn,count(*) over (order by cn rows between 0 following and 1 following) as c from sale; cn | c ----+--- 1 | 2 1 | 2 1 | 2 1 | 2 1 | 2 2 | 2 2 | 2 3 | 2 3 | 2 3 | 2 4 | 2 4 | 1 (12 rows) select cn,count(*) over (order by cn rows between 1 following and 2 following) as c from sale; cn | c ----+--- 1 | 2 1 | 2 1 | 2 1 | 2 1 | 2 2 | 2 2 | 2 3 | 2 3 | 2 3 | 2 4 | 1 4 | 0 (12 rows) select cn,count(*) over (order by cn rows between unbounded preceding and 2 preceding) as c from sale; cn | c ----+---- 1 | 0 1 | 0 1 | 1 1 | 2 1 | 3 2 | 4 2 | 5 3 | 6 3 | 7 3 | 8 4 | 9 4 | 10 (12 rows) select cn,count(*) over (order by cn rows between unbounded preceding and 0 preceding) as c from sale; cn | c ----+---- 1 | 1 1 | 2 1 | 3 1 | 4 1 | 5 2 | 6 2 | 7 3 | 8 3 | 9 3 | 10 4 | 11 4 | 12 (12 rows) select cn,count(*) over (order by cn rows between unbounded preceding and 2 following) as c from sale; cn | c ----+---- 1 | 3 1 | 4 1 | 5 1 | 6 1 | 7 2 | 8 2 | 9 3 | 10 3 | 11 3 | 12 4 | 12 4 | 12 (12 rows) select cn,count(*) over (order by cn rows between 2 preceding and unbounded following) as c from sale; cn | c ----+---- 1 | 12 1 | 12 1 | 12 1 | 11 1 | 10 2 | 9 2 | 8 3 | 7 3 | 6 3 | 5 4 | 4 4 | 3 (12 rows) select cn,count(*) over (order by cn rows between 0 preceding and unbounded following) as c from sale; cn | c ----+---- 1 | 12 1 | 11 1 | 10 1 | 9 1 | 8 2 | 7 2 | 6 3 | 5 3 | 4 3 | 3 4 | 2 4 | 1 (12 rows) select cn,count(*) over (order by cn rows between 0 following and unbounded following) as c from sale; cn | c ----+---- 1 | 12 1 | 11 1 | 10 1 | 9 1 | 8 2 | 7 2 | 6 3 | 5 3 | 4 3 | 3 4 | 2 4 | 1 (12 rows) select cn,count(*) over (order by cn rows between 1 following and unbounded following) as c from sale; cn | c ----+---- 1 | 11 1 | 10 1 | 9 1 | 8 1 | 7 2 | 6 2 | 5 3 | 4 3 | 3 3 | 2 4 | 1 4 | 0 (12 rows) select cn,count(*) over (order by cn rows between unbounded preceding and unbounded following) as c from sale; cn | c ----+---- 1 | 12 1 | 12 1 | 12 1 | 12 1 | 12 2 | 12 2 | 12 3 | 12 3 | 12 3 | 12 4 | 12 4 | 12 (12 rows) select cn,count(*) over (order by cn desc rows between 2 preceding and 1 preceding) as c from sale; cn | c ----+--- 4 | 0 4 | 1 3 | 2 3 | 2 3 | 2 2 | 2 2 | 2 1 | 2 1 | 2 1 | 2 1 | 2 1 | 2 (12 rows) select cn,count(*) over (order by cn desc rows between 2 preceding and 0 preceding) as c from sale; cn | c ----+--- 4 | 1 4 | 2 3 | 3 3 | 3 3 | 3 2 | 3 2 | 3 1 | 3 1 | 3 1 | 3 1 | 3 1 | 3 (12 rows) select cn,count(*) over (order by cn desc rows between 2 preceding and 1 following) as c from sale; cn | c ----+--- 4 | 2 4 | 3 3 | 4 3 | 4 3 | 4 2 | 4 2 | 4 1 | 4 1 | 4 1 | 4 1 | 4 1 | 3 (12 rows) select cn,count(*) over (order by cn desc rows between 0 preceding and 1 following) as c from sale; cn | c ----+--- 4 | 2 4 | 2 3 | 2 3 | 2 3 | 2 2 | 2 2 | 2 1 | 2 1 | 2 1 | 2 1 | 2 1 | 1 (12 rows) select cn,count(*) over (order by cn desc rows between 0 following and 1 following) as c from sale; cn | c ----+--- 4 | 2 4 | 2 3 | 2 3 | 2 3 | 2 2 | 2 2 | 2 1 | 2 1 | 2 1 | 2 1 | 2 1 | 1 (12 rows) select cn,count(*) over (order by cn desc rows between 1 following and 2 following) as c from sale; cn | c ----+--- 4 | 2 4 | 2 3 | 2 3 | 2 3 | 2 2 | 2 2 | 2 1 | 2 1 | 2 1 | 2 1 | 1 1 | 0 (12 rows) select cn,count(*) over (order by cn desc rows between unbounded preceding and 2 preceding) as c from sale; cn | c ----+---- 4 | 0 4 | 0 3 | 1 3 | 2 3 | 3 2 | 4 2 | 5 1 | 6 1 | 7 1 | 8 1 | 9 1 | 10 (12 rows) select cn,count(*) over (order by cn desc rows between unbounded preceding and 0 preceding) as c from sale; cn | c ----+---- 4 | 1 4 | 2 3 | 3 3 | 4 3 | 5 2 | 6 2 | 7 1 | 8 1 | 9 1 | 10 1 | 11 1 | 12 (12 rows) select cn,count(*) over (order by cn desc rows between unbounded preceding and 2 following) as c from sale; cn | c ----+---- 4 | 3 4 | 4 3 | 5 3 | 6 3 | 7 2 | 8 2 | 9 1 | 10 1 | 11 1 | 12 1 | 12 1 | 12 (12 rows) select cn,count(*) over (order by cn desc rows between 2 preceding and unbounded following) as c from sale; cn | c ----+---- 4 | 12 4 | 12 3 | 12 3 | 11 3 | 10 2 | 9 2 | 8 1 | 7 1 | 6 1 | 5 1 | 4 1 | 3 (12 rows) select cn,count(*) over (order by cn desc rows between 0 preceding and unbounded following) as c from sale; cn | c ----+---- 4 | 12 4 | 11 3 | 10 3 | 9 3 | 8 2 | 7 2 | 6 1 | 5 1 | 4 1 | 3 1 | 2 1 | 1 (12 rows) select cn,count(*) over (order by cn desc rows between 0 following and unbounded following) as c from sale; cn | c ----+---- 4 | 12 4 | 11 3 | 10 3 | 9 3 | 8 2 | 7 2 | 6 1 | 5 1 | 4 1 | 3 1 | 2 1 | 1 (12 rows) select cn,count(*) over (order by cn desc rows between 1 following and unbounded following) as c from sale; cn | c ----+---- 4 | 11 4 | 10 3 | 9 3 | 8 3 | 7 2 | 6 2 | 5 1 | 4 1 | 3 1 | 2 1 | 1 1 | 0 (12 rows) select cn,count(*) over (order by cn desc rows between unbounded preceding and unbounded following) as c from sale; cn | c ----+---- 4 | 12 4 | 12 3 | 12 3 | 12 3 | 12 2 | 12 2 | 12 1 | 12 1 | 12 1 | 12 1 | 12 1 | 12 (12 rows) select cn,count(*) over (order by cn range between 2 preceding and 1 preceding) as c from sale; cn | c ----+--- 1 | 0 1 | 0 1 | 0 1 | 0 1 | 0 2 | 5 2 | 5 3 | 7 3 | 7 3 | 7 4 | 5 4 | 5 (12 rows) select cn,count(*) over (order by cn range between 2 preceding and 0 preceding) as c from sale; cn | c ----+---- 1 | 5 1 | 5 1 | 5 1 | 5 1 | 5 2 | 7 2 | 7 3 | 10 3 | 10 3 | 10 4 | 7 4 | 7 (12 rows) select cn,count(*) over (order by cn range between 2 preceding and 1 following) as c from sale; cn | c ----+---- 1 | 7 1 | 7 1 | 7 1 | 7 1 | 7 2 | 10 2 | 10 3 | 12 3 | 12 3 | 12 4 | 7 4 | 7 (12 rows) select cn,count(*) over (order by cn range between 0 preceding and 1 following) as c from sale; cn | c ----+--- 1 | 7 1 | 7 1 | 7 1 | 7 1 | 7 2 | 5 2 | 5 3 | 5 3 | 5 3 | 5 4 | 2 4 | 2 (12 rows) select cn,count(*) over (order by cn range between 0 following and 1 following) as c from sale; cn | c ----+--- 1 | 7 1 | 7 1 | 7 1 | 7 1 | 7 2 | 5 2 | 5 3 | 5 3 | 5 3 | 5 4 | 2 4 | 2 (12 rows) select cn,count(*) over (order by cn range between 1 following and 2 following) as c from sale; cn | c ----+--- 1 | 5 1 | 5 1 | 5 1 | 5 1 | 5 2 | 5 2 | 5 3 | 2 3 | 2 3 | 2 4 | 0 4 | 0 (12 rows) select cn,count(*) over (order by cn range between unbounded preceding and 2 preceding) as c from sale; cn | c ----+--- 1 | 0 1 | 0 1 | 0 1 | 0 1 | 0 2 | 0 2 | 0 3 | 5 3 | 5 3 | 5 4 | 7 4 | 7 (12 rows) select cn,count(*) over (order by cn range between unbounded preceding and 0 preceding) as c from sale; cn | c ----+---- 1 | 5 1 | 5 1 | 5 1 | 5 1 | 5 2 | 7 2 | 7 3 | 10 3 | 10 3 | 10 4 | 12 4 | 12 (12 rows) select cn,count(*) over (order by cn range between unbounded preceding and 2 following) as c from sale; cn | c ----+---- 1 | 10 1 | 10 1 | 10 1 | 10 1 | 10 2 | 12 2 | 12 3 | 12 3 | 12 3 | 12 4 | 12 4 | 12 (12 rows) select cn,count(*) over (order by cn range between 2 preceding and unbounded following) as c from sale; cn | c ----+---- 1 | 12 1 | 12 1 | 12 1 | 12 1 | 12 2 | 12 2 | 12 3 | 12 3 | 12 3 | 12 4 | 7 4 | 7 (12 rows) select cn,count(*) over (order by cn range between 0 preceding and unbounded following) as c from sale; cn | c ----+---- 1 | 12 1 | 12 1 | 12 1 | 12 1 | 12 2 | 7 2 | 7 3 | 5 3 | 5 3 | 5 4 | 2 4 | 2 (12 rows) select cn,count(*) over (order by cn range between 0 following and unbounded following) as c from sale; cn | c ----+---- 1 | 12 1 | 12 1 | 12 1 | 12 1 | 12 2 | 7 2 | 7 3 | 5 3 | 5 3 | 5 4 | 2 4 | 2 (12 rows) select cn,count(*) over (order by cn range between 1 following and unbounded following) as c from sale; cn | c ----+--- 1 | 7 1 | 7 1 | 7 1 | 7 1 | 7 2 | 5 2 | 5 3 | 2 3 | 2 3 | 2 4 | 0 4 | 0 (12 rows) select cn,count(*) over (order by cn range between unbounded preceding and unbounded following) as c from sale; cn | c ----+---- 1 | 12 1 | 12 1 | 12 1 | 12 1 | 12 2 | 12 2 | 12 3 | 12 3 | 12 3 | 12 4 | 12 4 | 12 (12 rows) select cn,count(*) over (order by cn desc range between 2 preceding and 1 preceding) as c from sale; cn | c ----+--- 4 | 0 4 | 0 3 | 2 3 | 2 3 | 2 2 | 5 2 | 5 1 | 5 1 | 5 1 | 5 1 | 5 1 | 5 (12 rows) select cn,count(*) over (order by cn desc range between 2 preceding and 0 preceding) as c from sale; cn | c ----+---- 4 | 2 4 | 2 3 | 5 3 | 5 3 | 5 2 | 7 2 | 7 1 | 10 1 | 10 1 | 10 1 | 10 1 | 10 (12 rows) select cn,count(*) over (order by cn desc range between 2 preceding and 1 following) as c from sale; cn | c ----+---- 4 | 5 4 | 5 3 | 7 3 | 7 3 | 7 2 | 12 2 | 12 1 | 10 1 | 10 1 | 10 1 | 10 1 | 10 (12 rows) select cn,count(*) over (order by cn desc range between 0 preceding and 1 following) as c from sale; cn | c ----+--- 4 | 5 4 | 5 3 | 5 3 | 5 3 | 5 2 | 7 2 | 7 1 | 5 1 | 5 1 | 5 1 | 5 1 | 5 (12 rows) select cn,count(*) over (order by cn desc range between 0 following and 1 following) as c from sale; cn | c ----+--- 4 | 5 4 | 5 3 | 5 3 | 5 3 | 5 2 | 7 2 | 7 1 | 5 1 | 5 1 | 5 1 | 5 1 | 5 (12 rows) select cn,count(*) over (order by cn desc range between 1 following and 2 following) as c from sale; cn | c ----+--- 4 | 5 4 | 5 3 | 7 3 | 7 3 | 7 2 | 5 2 | 5 1 | 0 1 | 0 1 | 0 1 | 0 1 | 0 (12 rows) select cn,count(*) over (order by cn desc range between unbounded preceding and 2 preceding) as c from sale; cn | c ----+--- 4 | 0 4 | 0 3 | 0 3 | 0 3 | 0 2 | 2 2 | 2 1 | 5 1 | 5 1 | 5 1 | 5 1 | 5 (12 rows) select cn,count(*) over (order by cn desc range between unbounded preceding and 0 preceding) as c from sale; cn | c ----+---- 4 | 2 4 | 2 3 | 5 3 | 5 3 | 5 2 | 7 2 | 7 1 | 12 1 | 12 1 | 12 1 | 12 1 | 12 (12 rows) select cn,count(*) over (order by cn desc range between unbounded preceding and 2 following) as c from sale; cn | c ----+---- 4 | 7 4 | 7 3 | 12 3 | 12 3 | 12 2 | 12 2 | 12 1 | 12 1 | 12 1 | 12 1 | 12 1 | 12 (12 rows) select cn,count(*) over (order by cn desc range between 2 preceding and unbounded following) as c from sale; cn | c ----+---- 4 | 12 4 | 12 3 | 12 3 | 12 3 | 12 2 | 12 2 | 12 1 | 10 1 | 10 1 | 10 1 | 10 1 | 10 (12 rows) select cn,count(*) over (order by cn desc range between 0 preceding and unbounded following) as c from sale; cn | c ----+---- 4 | 12 4 | 12 3 | 10 3 | 10 3 | 10 2 | 7 2 | 7 1 | 5 1 | 5 1 | 5 1 | 5 1 | 5 (12 rows) select cn,count(*) over (order by cn desc range between 0 following and unbounded following) as c from sale; cn | c ----+---- 4 | 12 4 | 12 3 | 10 3 | 10 3 | 10 2 | 7 2 | 7 1 | 5 1 | 5 1 | 5 1 | 5 1 | 5 (12 rows) select cn,count(*) over (order by cn desc range between 1 following and unbounded following) as c from sale; cn | c ----+---- 4 | 10 4 | 10 3 | 7 3 | 7 3 | 7 2 | 5 2 | 5 1 | 0 1 | 0 1 | 0 1 | 0 1 | 0 (12 rows) select cn,count(*) over (order by cn desc range between unbounded preceding and unbounded following) as c from sale; cn | c ----+---- 4 | 12 4 | 12 3 | 12 3 | 12 3 | 12 2 | 12 2 | 12 1 | 12 1 | 12 1 | 12 1 | 12 1 | 12 (12 rows) -- MPP-1885 SELECT sale.vn, COUNT(vn) OVER(order by sale.vn asc range between unbounded preceding and 2 preceding) FROM sale; vn | count ----+------- 10 | 0 20 | 1 30 | 2 30 | 2 30 | 2 30 | 2 40 | 6 40 | 6 40 | 6 40 | 6 50 | 10 50 | 10 (12 rows) -- aggregates in multiple key levels select cn,pn,vn, count(*) over (order by cn) as c1, count(*) over (order by cn,vn) as c2, count(*) over (order by cn,vn,pn) as c3 from sale; cn | pn | vn | c1 | c2 | c3 ----+-----+----+----+----+---- 1 | 200 | 10 | 5 | 1 | 1 1 | 100 | 20 | 5 | 2 | 2 1 | 300 | 30 | 5 | 4 | 3 1 | 500 | 30 | 5 | 4 | 4 1 | 400 | 50 | 5 | 5 | 5 2 | 100 | 40 | 7 | 6 | 6 2 | 400 | 50 | 7 | 7 | 7 3 | 500 | 30 | 10 | 9 | 8 3 | 600 | 30 | 10 | 9 | 9 3 | 200 | 40 | 10 | 10 | 10 4 | 700 | 40 | 12 | 12 | 11 4 | 800 | 40 | 12 | 12 | 12 (12 rows) select cn,pn,vn, count(*) over (order by ord range between 2 preceding and 2 following) as c1, count(*) over (order by ord,cn,vn rows between 2 preceding and 2 following) as c2, count(*) over (order by ord,cn,vn,pn) as c3 from sale_ord; cn | pn | vn | c1 | c2 | c3 ----+-----+----+----+----+---- 2 | 100 | 40 | 3 | 3 | 1 1 | 200 | 10 | 4 | 4 | 2 3 | 200 | 40 | 5 | 5 | 3 1 | 100 | 20 | 5 | 5 | 4 1 | 300 | 30 | 5 | 5 | 5 1 | 400 | 50 | 5 | 5 | 6 2 | 400 | 50 | 5 | 5 | 7 1 | 500 | 30 | 5 | 5 | 8 3 | 500 | 30 | 5 | 5 | 9 3 | 600 | 30 | 5 | 5 | 10 4 | 700 | 40 | 4 | 4 | 11 4 | 800 | 40 | 3 | 3 | 12 (12 rows) -- MPP-1897 SELECT sale.cn,sale.qty, SUM(floor(sale.qty)) OVER(order by sale.cn asc range between 2 following and 2 following) FROM sale; --mvd 1->3 cn | qty | sum ----+------+----- 1 | 1 | 25 1 | 1 | 25 1 | 1 | 25 1 | 1 | 25 1 | 12 | 25 2 | 1100 | 2 2 | 1 | 2 3 | 12 | 3 | 1 | 3 | 12 | 4 | 1 | 4 | 1 | (12 rows) SELECT sale.cn,sale.qty, SUM(floor(sale.qty)) OVER(order by ord,sale.cn asc rows between 2 following and 2 following) as sum FROM sale_ord as sale; cn | qty | sum ----+------+----- 2 | 1100 | 1 1 | 1 | 1 3 | 1 | 1 1 | 1 | 1 1 | 1 | 1 1 | 1 | 12 2 | 1 | 12 1 | 12 | 12 3 | 12 | 1 3 | 12 | 1 4 | 1 | 4 | 1 | (12 rows) -- MPP-1892 SELECT sale.vn,sale.cn,sale.prc,sale.pn,sale.prc, COUNT(floor(sale.prc)) OVER(partition by sale.vn,sale.cn,sale.prc,sale.vn order by sale.pn asc range between unbounded preceding and 1 preceding) as count from sale; --mvd 1,2,3->6 vn | cn | prc | pn | prc | count ----+----+------+-----+------+------- 10 | 1 | 0 | 200 | 0 | 0 20 | 1 | 0 | 100 | 0 | 0 30 | 1 | 0 | 300 | 0 | 0 30 | 1 | 5 | 500 | 5 | 0 30 | 3 | 5 | 500 | 5 | 0 30 | 3 | 5 | 600 | 5 | 1 40 | 3 | 0 | 200 | 0 | 0 40 | 4 | 1 | 700 | 1 | 0 40 | 4 | 1 | 800 | 1 | 1 50 | 1 | 0 | 400 | 0 | 0 40 | 2 | 2400 | 100 | 2400 | 0 50 | 2 | 0 | 400 | 0 | 0 (12 rows) -- MPP-1893 SELECT sale.prc,sale.cn,sale.vn,sale.pn,sale.cn, AVG(floor(sale.pn-sale.cn)) OVER(partition by sale.prc,sale.cn order by sale.vn desc range between 1 preceding and unbounded following) as avg FROM sale; --mvd 1,2->6 prc | cn | vn | pn | cn | avg ------+----+----+-----+----+----- 0 | 1 | 50 | 400 | 1 | 249 0 | 1 | 30 | 300 | 1 | 199 0 | 1 | 20 | 100 | 1 | 149 0 | 1 | 10 | 200 | 1 | 199 0 | 3 | 40 | 200 | 3 | 197 1 | 4 | 40 | 700 | 4 | 746 1 | 4 | 40 | 800 | 4 | 746 5 | 1 | 30 | 500 | 1 | 499 5 | 3 | 30 | 500 | 3 | 547 5 | 3 | 30 | 600 | 3 | 547 0 | 2 | 50 | 400 | 2 | 398 2400 | 2 | 40 | 100 | 2 | 98 (12 rows) SELECT sale.prc,sale.cn,sale.vn,sale.pn,sale.cn, AVG(floor(sale.pn-sale.cn)) OVER(partition by sale.prc,sale.cn order by sale.vn desc range between 0 preceding and unbounded following) as avg FROM sale; --mvd 1,2->6 prc | cn | vn | pn | cn | avg ------+----+----+-----+----+----- 0 | 1 | 50 | 400 | 1 | 249 0 | 1 | 30 | 300 | 1 | 199 0 | 1 | 20 | 100 | 1 | 149 0 | 1 | 10 | 200 | 1 | 199 0 | 3 | 40 | 200 | 3 | 197 1 | 4 | 40 | 700 | 4 | 746 1 | 4 | 40 | 800 | 4 | 746 5 | 1 | 30 | 500 | 1 | 499 5 | 3 | 30 | 500 | 3 | 547 5 | 3 | 30 | 600 | 3 | 547 0 | 2 | 50 | 400 | 2 | 398 2400 | 2 | 40 | 100 | 2 | 98 (12 rows) -- MPP-1895 SELECT sale.prc,sale.vn, COUNT(vn) OVER(partition by sale.prc order by sale.vn asc range between 3 preceding and 3 following) FROM sale; --mvd 1->3 prc | vn | count ------+----+------- 1 | 40 | 2 1 | 40 | 2 0 | 10 | 1 0 | 20 | 1 0 | 30 | 1 0 | 40 | 1 0 | 50 | 2 0 | 50 | 2 5 | 30 | 3 5 | 30 | 3 5 | 30 | 3 2400 | 40 | 1 (12 rows) -- MPP-1898 SELECT sale.vn,sale.qty, SUM(floor(sale.qty)) OVER(order by sale.vn desc range between 0 following and 2 following ) as sum from sale; --mvd 1->3 vn | qty | sum ----+------+------ 50 | 1 | 2 50 | 1 | 2 40 | 1 | 1103 40 | 1100 | 1103 40 | 1 | 1103 40 | 1 | 1103 30 | 12 | 37 30 | 12 | 37 30 | 1 | 37 30 | 12 | 37 20 | 1 | 1 10 | 1 | 1 (12 rows) -- MPP-1907, MPP-1912 -- begin_equivalent SELECT sale.pn, COUNT(floor(sale.pn)) OVER(order by sale.pn desc rows between 4 preceding and current row) as count FROM sale; pn | count -----+------- 800 | 1 700 | 2 600 | 3 500 | 4 500 | 5 400 | 5 400 | 5 300 | 5 200 | 5 200 | 5 100 | 5 100 | 5 (12 rows) SELECT sale.pn, COUNT(floor(sale.pn)) OVER(order by sale.pn desc rows between 4 preceding and 0 preceding) as count FROM sale; pn | count -----+------- 800 | 1 700 | 2 600 | 3 500 | 4 500 | 5 400 | 5 400 | 5 300 | 5 200 | 5 200 | 5 100 | 5 100 | 5 (12 rows) SELECT sale.pn, COUNT(floor(sale.pn)) OVER(order by sale.pn desc rows between 4 preceding and 0 following) as count FROM sale; pn | count -----+------- 800 | 1 700 | 2 600 | 3 500 | 4 500 | 5 400 | 5 400 | 5 300 | 5 200 | 5 200 | 5 100 | 5 100 | 5 (12 rows) SELECT sale.pn, COUNT(floor(sale.pn)) OVER(order by sale.pn desc rows 4 preceding) as count FROM sale; pn | count -----+------- 800 | 1 700 | 2 600 | 3 500 | 4 500 | 5 400 | 5 400 | 5 300 | 5 200 | 5 200 | 5 100 | 5 100 | 5 (12 rows) -- end_equivalent -- begin_equivalent SELECT sale.pn, COUNT(floor(sale.pn)) OVER(order by sale.pn desc range between 4 preceding and current row) as count FROM sale; pn | count -----+------- 800 | 1 700 | 1 600 | 1 500 | 2 500 | 2 400 | 2 400 | 2 300 | 1 200 | 2 200 | 2 100 | 2 100 | 2 (12 rows) SELECT sale.pn, COUNT(floor(sale.pn)) OVER(order by sale.pn desc range between 4 preceding and 0 preceding) as count FROM sale; pn | count -----+------- 800 | 1 700 | 1 600 | 1 500 | 2 500 | 2 400 | 2 400 | 2 300 | 1 200 | 2 200 | 2 100 | 2 100 | 2 (12 rows) SELECT sale.pn, COUNT(floor(sale.pn)) OVER(order by sale.pn desc range between 4 preceding and 0 following) as count FROM sale; pn | count -----+------- 800 | 1 700 | 1 600 | 1 500 | 2 500 | 2 400 | 2 400 | 2 300 | 1 200 | 2 200 | 2 100 | 2 100 | 2 (12 rows) SELECT sale.pn, COUNT(floor(sale.pn)) OVER(order by sale.pn desc range 4 preceding) as count FROM sale; pn | count -----+------- 800 | 1 700 | 1 600 | 1 500 | 2 500 | 2 400 | 2 400 | 2 300 | 1 200 | 2 200 | 2 100 | 2 100 | 2 (12 rows) -- end_equivalent -- MPP-1915 select cn, qty, sum(qty) over(order by cn) as sum, cume_dist() over(order by cn) as cume1 from sale; --mvd 1->3 cn | qty | sum | cume1 ----+------+------+------------------- 1 | 1 | 16 | 0.416666666666667 1 | 1 | 16 | 0.416666666666667 1 | 1 | 16 | 0.416666666666667 1 | 1 | 16 | 0.416666666666667 1 | 12 | 16 | 0.416666666666667 2 | 1100 | 1117 | 0.583333333333333 2 | 1 | 1117 | 0.583333333333333 3 | 12 | 1142 | 0.833333333333333 3 | 1 | 1142 | 0.833333333333333 3 | 12 | 1142 | 0.833333333333333 4 | 1 | 1144 | 1 4 | 1 | 1144 | 1 (12 rows) SELECT sale.cn, SUM(sale.cn) OVER(order by sale.cn asc range 1 preceding ),COUNT(floor(sale.vn)) OVER(order by sale.cn asc range 1 preceding ) FROM sale; cn | sum | count ----+-----+------- 1 | 5 | 5 1 | 5 | 5 1 | 5 | 5 1 | 5 | 5 1 | 5 | 5 2 | 9 | 7 2 | 9 | 7 3 | 13 | 5 3 | 13 | 5 3 | 13 | 5 4 | 17 | 5 4 | 17 | 5 (12 rows) SELECT sale.cn, SUM(sale.cn) OVER(order by sale.cn asc range 2 preceding ),COUNT(floor(sale.vn)) OVER(order by sale.cn asc range 1 preceding ) FROM sale; cn | sum | count ----+-----+------- 1 | 5 | 5 1 | 5 | 5 1 | 5 | 5 1 | 5 | 5 1 | 5 | 5 2 | 9 | 7 2 | 9 | 7 3 | 18 | 5 3 | 18 | 5 3 | 18 | 5 4 | 21 | 5 4 | 21 | 5 (12 rows) select pn, count(*) over (order by pn range between 100 preceding and 100 following), count(*) over (order by pn range between 200 preceding and 200 following) from sale; pn | count | count -----+-------+------- 100 | 4 | 5 100 | 4 | 5 200 | 5 | 7 200 | 5 | 7 300 | 5 | 9 400 | 5 | 8 400 | 5 | 8 500 | 5 | 7 500 | 5 | 7 600 | 4 | 7 700 | 3 | 5 800 | 2 | 3 (12 rows) -- MPP-1923 SELECT sale.cn,sale.pn,sale.vn, CUME_DIST() OVER(partition by sale.cn,sale.pn order by sale.vn desc,sale.pn desc,sale.cn asc) FROM sale; --mvd 1,2->4 cn | pn | vn | cume_dist ----+-----+----+----------- 1 | 100 | 20 | 1 1 | 200 | 10 | 1 2 | 400 | 50 | 1 3 | 200 | 40 | 1 3 | 600 | 30 | 1 4 | 800 | 40 | 1 1 | 300 | 30 | 1 1 | 400 | 50 | 1 1 | 500 | 30 | 1 2 | 100 | 40 | 1 3 | 500 | 30 | 1 4 | 700 | 40 | 1 (12 rows) SELECT sale.cn,sale.vn,sale.pn, SUM((cn*100+pn/100)%100) OVER(partition by sale.vn,sale.pn order by sale.pn asc rows between 1 following and unbounded following) as sum from sale; --mvd 2,3->4 cn | vn | pn | sum ----+----+-----+----- 1 | 30 | 300 | 1 | 30 | 500 | 5 3 | 30 | 500 | 4 | 40 | 800 | 1 | 50 | 400 | 4 2 | 50 | 400 | 1 | 10 | 200 | 1 | 20 | 100 | 3 | 30 | 600 | 2 | 40 | 100 | 3 | 40 | 200 | 4 | 40 | 700 | (12 rows) -- MPP-1924 SELECT sale.cn, COUNT(cn) OVER(order by sale.cn range between 7 following and 7 following) as count FROM sale; cn | count ----+------- 1 | 0 1 | 0 1 | 0 1 | 0 1 | 0 2 | 0 2 | 0 3 | 0 3 | 0 3 | 0 4 | 0 4 | 0 (12 rows) -- MPP-1925 SELECT sale.pn,sale.vn, COUNT(floor(sale.cn-sale.prc)) OVER(order by sale.pn asc,sale.vn asc,sale.vn desc rows between current row and 2 following ) as count,sale.pn, CUME_DIST() OVER(order by sale.pn asc) as cume_dist FROM sale; pn | vn | count | pn | cume_dist -----+----+-------+-----+------------------- 100 | 20 | 3 | 100 | 0.166666666666667 100 | 40 | 3 | 100 | 0.166666666666667 200 | 10 | 3 | 200 | 0.333333333333333 200 | 40 | 3 | 200 | 0.333333333333333 300 | 30 | 3 | 300 | 0.416666666666667 400 | 50 | 3 | 400 | 0.583333333333333 400 | 50 | 3 | 400 | 0.583333333333333 500 | 30 | 3 | 500 | 0.75 500 | 30 | 3 | 500 | 0.75 600 | 30 | 3 | 600 | 0.833333333333333 700 | 40 | 2 | 700 | 0.916666666666667 800 | 40 | 1 | 800 | 1 (12 rows) -- MPP-1874 CREATE TABLE FACT_TEST (DATE_KEY NUMERIC(10,0) NOT NULL, BCOOKIE text NOT NULL, TIME_KEY INTEGER NOT NULL, EVENT_TYPE text NOT NULL ); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'date_key' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into fact_test values (20070101, 'W', 100, 'c'), (20070101, 'W', 100, 'p'), (20070101, 'B', 100, 'c'), (20070101, 'A', 10100101, 'p'), (20070101, 'A', 20100101, 'p'), (20070101, 'B', 101, 'p'), (20070101, 'C', 105, 'p'), (20070101, 'D', 107, 'p'), (20070101, 'E', 10, 'c'), (20070101, 'E', 10, 'p'), (20070101, 'A', 101, 'c'), (20070101, 'A', 101, 'p'), (20070101, 'A', 10100101, 'p'); select date_key, bcookie, time_key, event_type, ( case when (time_key- lag(time_key, 1, NULL) over ( partition by date_key, bcookie order by date_key, bcookie, time_key, event_type) ) > 1800 then 1 else 0 end ) AS time_check from fact_test order by date_key, bcookie, time_key, event_type, time_check; date_key | bcookie | time_key | event_type | time_check ----------+---------+----------+------------+------------ 20070101 | A | 101 | c | 0 20070101 | A | 101 | p | 0 20070101 | A | 10100101 | p | 0 20070101 | A | 10100101 | p | 1 20070101 | A | 20100101 | p | 1 20070101 | B | 100 | c | 0 20070101 | B | 101 | p | 0 20070101 | C | 105 | p | 0 20070101 | D | 107 | p | 0 20070101 | E | 10 | c | 0 20070101 | E | 10 | p | 0 20070101 | W | 100 | c | 0 20070101 | W | 100 | p | 0 (13 rows) drop table fact_test; -- MPP-1929 SELECT vn,pn,cn, TO_CHAR(COALESCE(CUME_DIST() OVER(partition by sale.vn,sale.pn order by sale.cn desc),0),'99999999.9999999') as cum_dist, TO_CHAR(COALESCE(CUME_DIST() OVER(partition by sale.vn,sale.pn order by sale.cn desc),0),'99999999.9999999') as cum_dist from sale; --mvd 1,2->4 vn | pn | cn | cum_dist | cum_dist ----+-----+----+-------------------+------------------- 30 | 300 | 1 | 1.0000000 | 1.0000000 30 | 500 | 3 | .5000000 | .5000000 30 | 500 | 1 | 1.0000000 | 1.0000000 40 | 800 | 4 | 1.0000000 | 1.0000000 50 | 400 | 2 | .5000000 | .5000000 50 | 400 | 1 | 1.0000000 | 1.0000000 10 | 200 | 1 | 1.0000000 | 1.0000000 20 | 100 | 1 | 1.0000000 | 1.0000000 30 | 600 | 3 | 1.0000000 | 1.0000000 40 | 100 | 2 | 1.0000000 | 1.0000000 40 | 200 | 3 | 1.0000000 | 1.0000000 40 | 700 | 4 | 1.0000000 | 1.0000000 (12 rows) select cn,pn,lag(pn,cn) over (order by ord,pn) from sale_ord; cn | pn | lag ----+-----+----- 2 | 100 | 1 | 200 | 100 3 | 200 | 1 | 100 | 200 1 | 300 | 100 1 | 400 | 300 2 | 400 | 300 1 | 500 | 400 3 | 500 | 400 3 | 600 | 400 4 | 700 | 400 4 | 800 | 500 (12 rows) select cn,pn,lead(pn,cn) over (order by ord,pn) from sale_ord; cn | pn | lead ----+-----+------ 2 | 100 | 200 1 | 200 | 200 3 | 200 | 400 1 | 100 | 300 1 | 300 | 400 1 | 400 | 400 2 | 400 | 500 1 | 500 | 500 3 | 500 | 800 3 | 600 | 4 | 700 | 4 | 800 | (12 rows) select vn,cn,pn,lead(pn,cn) over (partition by vn order by cn,pn) from sale; --mvd 1->4 vn | cn | pn | lead ----+----+-----+------ 10 | 1 | 200 | 20 | 1 | 100 | 30 | 1 | 300 | 500 30 | 1 | 500 | 500 30 | 3 | 500 | 30 | 3 | 600 | 40 | 2 | 100 | 700 40 | 3 | 200 | 40 | 4 | 700 | 40 | 4 | 800 | 50 | 1 | 400 | 400 50 | 2 | 400 | (12 rows) select vn,cn,pn,lag(pn,cn) over (partition by vn order by cn,pn) from sale; --mvd 1->4 vn | cn | pn | lag ----+----+-----+----- 10 | 1 | 200 | 20 | 1 | 100 | 30 | 1 | 300 | 30 | 1 | 500 | 300 30 | 3 | 500 | 30 | 3 | 600 | 300 40 | 2 | 100 | 40 | 3 | 200 | 40 | 4 | 700 | 40 | 4 | 800 | 50 | 1 | 400 | 50 | 2 | 400 | (12 rows) -- MPP-1934 SELECT sale.dt,sale.vn,sale.qty,sale.pn,sale.cn, LEAD(cast(floor(sale.cn+sale.vn) as int),cast (floor(sale.qty) as int),NULL) OVER(partition by sale.dt,sale.vn,sale.qty order by sale.pn desc,sale.cn desc) as lead FROM sale; --mvd 1,2,3->6 dt | vn | qty | pn | cn | lead ------------+----+------+-----+----+------ 01-01-1401 | 40 | 1100 | 100 | 2 | 03-01-1401 | 10 | 1 | 200 | 1 | 05-02-1401 | 30 | 1 | 300 | 1 | 06-01-1401 | 40 | 1 | 800 | 4 | 44 06-01-1401 | 40 | 1 | 700 | 4 | 06-01-1401 | 50 | 1 | 400 | 2 | 51 06-01-1401 | 50 | 1 | 400 | 1 | 04-01-1401 | 40 | 1 | 200 | 3 | 05-01-1401 | 20 | 1 | 100 | 1 | 06-01-1401 | 30 | 12 | 600 | 3 | 06-01-1401 | 30 | 12 | 500 | 3 | 06-01-1401 | 30 | 12 | 500 | 1 | (12 rows) -- MPP-1935 SELECT sale.vn,sale.qty,sale.prc, LAG(cast(floor(sale.qty*sale.prc) as int),cast (floor(sale.prc) as int),NULL) OVER(order by ord,sale.vn asc) as lag from sale_ord as sale; vn | qty | prc | lag ----+------+------+----- 40 | 1100 | 2400 | 10 | 1 | 0 | 0 40 | 1 | 0 | 0 20 | 1 | 0 | 0 30 | 1 | 0 | 0 50 | 1 | 0 | 0 50 | 1 | 0 | 0 30 | 12 | 5 | 0 30 | 12 | 5 | 0 30 | 12 | 5 | 0 40 | 1 | 1 | 60 40 | 1 | 1 | 1 (12 rows) -- MPP-1936 SELECT sale.vn,sale.prc,sale.qty, COUNT(floor(sale.prc)) OVER(order by sale.vn asc), LAG(cast(floor(sale.qty*sale.prc) as int),cast (floor(sale.prc) as int),NULL) OVER(order by ord,sale.vn asc) as lag from sale_ord as sale; vn | prc | qty | count | lag ----+------+------+-------+----- 40 | 2400 | 1100 | 10 | 10 | 0 | 1 | 1 | 0 40 | 0 | 1 | 10 | 0 20 | 0 | 1 | 2 | 0 30 | 0 | 1 | 6 | 0 50 | 0 | 1 | 12 | 0 50 | 0 | 1 | 12 | 0 30 | 5 | 12 | 6 | 0 30 | 5 | 12 | 6 | 0 30 | 5 | 12 | 6 | 0 40 | 1 | 1 | 10 | 60 40 | 1 | 1 | 10 | 1 (12 rows) select cn,vn,qty, sum(qty) over(order by ord,cn rows between 1 preceding and 0 following) as sum1, sum(qty) over(order by ord,cn rows between 1 preceding and 1 following) as sum2 from sale_ord; cn | vn | qty | sum1 | sum2 ----+----+------+------+------ 2 | 40 | 1100 | 1100 | 1101 1 | 10 | 1 | 1101 | 1102 3 | 40 | 1 | 2 | 3 1 | 20 | 1 | 2 | 3 1 | 30 | 1 | 2 | 3 1 | 50 | 1 | 2 | 3 2 | 50 | 1 | 2 | 14 1 | 30 | 12 | 13 | 25 3 | 30 | 12 | 24 | 36 3 | 30 | 12 | 24 | 25 4 | 40 | 1 | 13 | 14 4 | 40 | 1 | 2 | 2 (12 rows) -- MPP-1933 SELECT sale.prc,sale.vn,sale.cn,sale.pn,sale.qty, LAG(cast(floor(sale.vn) as int),cast (floor(sale.prc) as int),NULL) OVER(partition by sale.prc,sale.vn,sale.cn,sale.pn order by sale.cn desc) as lag1 from sale; --mvd 1,2,3,4->6 prc | vn | cn | pn | qty | lag1 ------+----+----+-----+------+------ 0 | 10 | 1 | 200 | 1 | 10 0 | 20 | 1 | 100 | 1 | 20 0 | 40 | 3 | 200 | 1 | 40 0 | 50 | 2 | 400 | 1 | 50 1 | 40 | 4 | 800 | 1 | 5 | 30 | 3 | 600 | 12 | 0 | 30 | 1 | 300 | 1 | 30 0 | 50 | 1 | 400 | 1 | 50 1 | 40 | 4 | 700 | 1 | 5 | 30 | 1 | 500 | 12 | 5 | 30 | 3 | 500 | 12 | 2400 | 40 | 2 | 100 | 1100 | (12 rows) SELECT sale.prc,sale.vn,sale.cn,sale.pn,sale.qty, LAG(cast(floor(sale.qty/sale.vn) as int),cast (floor(sale.pn) as int),NULL) OVER(partition by sale.prc,sale.vn,sale.cn,sale.pn order by sale.cn desc) as lag2 from sale; --mvd 1,2,3,4->6 prc | vn | cn | pn | qty | lag2 ------+----+----+-----+------+------ 0 | 30 | 1 | 300 | 1 | 0 | 50 | 1 | 400 | 1 | 1 | 40 | 4 | 700 | 1 | 5 | 30 | 1 | 500 | 12 | 5 | 30 | 3 | 500 | 12 | 2400 | 40 | 2 | 100 | 1100 | 0 | 10 | 1 | 200 | 1 | 0 | 20 | 1 | 100 | 1 | 0 | 40 | 3 | 200 | 1 | 0 | 50 | 2 | 400 | 1 | 1 | 40 | 4 | 800 | 1 | 5 | 30 | 3 | 600 | 12 | (12 rows) SELECT sale.prc,sale.vn,sale.cn,sale.pn,sale.qty, LAG(cast(floor(sale.vn) as int),cast (floor(sale.prc) as int),NULL) OVER(partition by sale.prc,sale.vn,sale.cn,sale.pn order by sale.cn desc) as lag1, LAG(cast(floor(sale.qty/sale.vn) as int),cast (floor(sale.pn) as int),NULL) OVER(partition by sale.prc,sale.vn,sale.cn,sale.pn order by sale.cn desc) as lag2 from sale; --mvd 1,2,3,4->6 prc | vn | cn | pn | qty | lag1 | lag2 ------+----+----+-----+------+------+------ 0 | 30 | 1 | 300 | 1 | 30 | 0 | 50 | 1 | 400 | 1 | 50 | 1 | 40 | 4 | 700 | 1 | | 5 | 30 | 1 | 500 | 12 | | 5 | 30 | 3 | 500 | 12 | | 2400 | 40 | 2 | 100 | 1100 | | 0 | 10 | 1 | 200 | 1 | 10 | 0 | 20 | 1 | 100 | 1 | 20 | 0 | 40 | 3 | 200 | 1 | 40 | 0 | 50 | 2 | 400 | 1 | 50 | 1 | 40 | 4 | 800 | 1 | | 5 | 30 | 3 | 600 | 12 | | (12 rows) -- MIN/MAX select cn,vn,min(vn) over (order by ord,cn rows between 2 preceding and 1 preceding) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 1 | 10 | 40 3 | 40 | 10 1 | 20 | 10 1 | 30 | 20 1 | 50 | 20 2 | 50 | 30 1 | 30 | 50 3 | 30 | 30 3 | 30 | 30 4 | 40 | 30 4 | 40 | 30 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between 2 preceding and 0 preceding) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 40 1 | 10 | 10 3 | 40 | 10 1 | 20 | 10 1 | 30 | 20 1 | 50 | 20 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 30 4 | 40 | 30 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between 2 preceding and 1 following) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 10 1 | 10 | 10 3 | 40 | 10 1 | 20 | 10 1 | 30 | 20 1 | 50 | 20 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 30 4 | 40 | 30 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between 0 preceding and 1 following) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 10 1 | 10 | 10 3 | 40 | 20 1 | 20 | 20 1 | 30 | 30 1 | 50 | 50 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between 0 following and 1 following) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 10 1 | 10 | 10 3 | 40 | 20 1 | 20 | 20 1 | 30 | 30 1 | 50 | 50 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between 1 following and 2 following) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 10 1 | 10 | 20 3 | 40 | 20 1 | 20 | 30 1 | 30 | 50 1 | 50 | 30 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 40 4 | 40 | 40 4 | 40 | (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between unbounded preceding and 2 preceding) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 1 | 10 | 3 | 40 | 40 1 | 20 | 10 1 | 30 | 10 1 | 50 | 10 2 | 50 | 10 1 | 30 | 10 3 | 30 | 10 3 | 30 | 10 4 | 40 | 10 4 | 40 | 10 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between unbounded preceding and 0 preceding) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 40 1 | 10 | 10 3 | 40 | 10 1 | 20 | 10 1 | 30 | 10 1 | 50 | 10 2 | 50 | 10 1 | 30 | 10 3 | 30 | 10 3 | 30 | 10 4 | 40 | 10 4 | 40 | 10 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between unbounded preceding and 2 following) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 10 1 | 10 | 10 3 | 40 | 10 1 | 20 | 10 1 | 30 | 10 1 | 50 | 10 2 | 50 | 10 1 | 30 | 10 3 | 30 | 10 3 | 30 | 10 4 | 40 | 10 4 | 40 | 10 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between 2 preceding and unbounded following) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 10 1 | 10 | 10 3 | 40 | 10 1 | 20 | 10 1 | 30 | 20 1 | 50 | 20 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 30 4 | 40 | 30 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between 0 preceding and unbounded following) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 10 1 | 10 | 10 3 | 40 | 20 1 | 20 | 20 1 | 30 | 30 1 | 50 | 30 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between 0 following and unbounded following) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 10 1 | 10 | 10 3 | 40 | 20 1 | 20 | 20 1 | 30 | 30 1 | 50 | 30 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between 1 following and unbounded following) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 10 1 | 10 | 20 3 | 40 | 20 1 | 20 | 30 1 | 30 | 30 1 | 50 | 30 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 40 4 | 40 | 40 4 | 40 | (12 rows) select cn,vn,min(vn) over (order by ord,cn rows between unbounded preceding and unbounded following) as min from sale_ord; cn | vn | min ----+----+----- 2 | 40 | 10 1 | 10 | 10 3 | 40 | 10 1 | 20 | 10 1 | 30 | 10 1 | 50 | 10 2 | 50 | 10 1 | 30 | 10 3 | 30 | 10 3 | 30 | 10 4 | 40 | 10 4 | 40 | 10 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between 2 preceding and 1 preceding) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 4 | 40 | 40 3 | 30 | 40 3 | 30 | 30 1 | 30 | 30 2 | 50 | 30 1 | 50 | 30 1 | 30 | 50 1 | 20 | 30 3 | 40 | 20 1 | 10 | 20 2 | 40 | 10 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between 2 preceding and 0 preceding) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 40 4 | 40 | 40 3 | 30 | 30 3 | 30 | 30 1 | 30 | 30 2 | 50 | 30 1 | 50 | 30 1 | 30 | 30 1 | 20 | 20 3 | 40 | 20 1 | 10 | 10 2 | 40 | 10 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between 2 preceding and 1 following) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 40 4 | 40 | 30 3 | 30 | 30 3 | 30 | 30 1 | 30 | 30 2 | 50 | 30 1 | 50 | 30 1 | 30 | 20 1 | 20 | 20 3 | 40 | 10 1 | 10 | 10 2 | 40 | 10 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between 0 preceding and 1 following) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 40 4 | 40 | 30 3 | 30 | 30 3 | 30 | 30 1 | 30 | 30 2 | 50 | 50 1 | 50 | 30 1 | 30 | 20 1 | 20 | 20 3 | 40 | 10 1 | 10 | 10 2 | 40 | 40 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between 0 following and 1 following) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 40 4 | 40 | 30 3 | 30 | 30 3 | 30 | 30 1 | 30 | 30 2 | 50 | 50 1 | 50 | 30 1 | 30 | 20 1 | 20 | 20 3 | 40 | 10 1 | 10 | 10 2 | 40 | 40 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between 1 following and 2 following) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 30 4 | 40 | 30 3 | 30 | 30 3 | 30 | 30 1 | 30 | 50 2 | 50 | 30 1 | 50 | 20 1 | 30 | 20 1 | 20 | 10 3 | 40 | 10 1 | 10 | 40 2 | 40 | (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between unbounded preceding and 2 preceding) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 4 | 40 | 3 | 30 | 40 3 | 30 | 40 1 | 30 | 30 2 | 50 | 30 1 | 50 | 30 1 | 30 | 30 1 | 20 | 30 3 | 40 | 30 1 | 10 | 20 2 | 40 | 20 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between unbounded preceding and 0 preceding) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 40 4 | 40 | 40 3 | 30 | 30 3 | 30 | 30 1 | 30 | 30 2 | 50 | 30 1 | 50 | 30 1 | 30 | 30 1 | 20 | 20 3 | 40 | 20 1 | 10 | 10 2 | 40 | 10 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between unbounded preceding and 2 following) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 30 4 | 40 | 30 3 | 30 | 30 3 | 30 | 30 1 | 30 | 30 2 | 50 | 30 1 | 50 | 20 1 | 30 | 20 1 | 20 | 10 3 | 40 | 10 1 | 10 | 10 2 | 40 | 10 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between 2 preceding and unbounded following) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 10 4 | 40 | 10 3 | 30 | 10 3 | 30 | 10 1 | 30 | 10 2 | 50 | 10 1 | 50 | 10 1 | 30 | 10 1 | 20 | 10 3 | 40 | 10 1 | 10 | 10 2 | 40 | 10 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between 0 preceding and unbounded following) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 10 4 | 40 | 10 3 | 30 | 10 3 | 30 | 10 1 | 30 | 10 2 | 50 | 10 1 | 50 | 10 1 | 30 | 10 1 | 20 | 10 3 | 40 | 10 1 | 10 | 10 2 | 40 | 40 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between 0 following and unbounded following) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 10 4 | 40 | 10 3 | 30 | 10 3 | 30 | 10 1 | 30 | 10 2 | 50 | 10 1 | 50 | 10 1 | 30 | 10 1 | 20 | 10 3 | 40 | 10 1 | 10 | 10 2 | 40 | 40 (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between 1 following and unbounded following) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 10 4 | 40 | 10 3 | 30 | 10 3 | 30 | 10 1 | 30 | 10 2 | 50 | 10 1 | 50 | 10 1 | 30 | 10 1 | 20 | 10 3 | 40 | 10 1 | 10 | 40 2 | 40 | (12 rows) select cn,vn,min(vn) over (order by ord desc,cn desc rows between unbounded preceding and unbounded following) as min from sale_ord; cn | vn | min ----+----+----- 4 | 40 | 10 4 | 40 | 10 3 | 30 | 10 3 | 30 | 10 1 | 30 | 10 2 | 50 | 10 1 | 50 | 10 1 | 30 | 10 1 | 20 | 10 3 | 40 | 10 1 | 10 | 10 2 | 40 | 10 (12 rows) select pn,vn,max(vn) over (order by pn range between 200 preceding and 150 preceding) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 100 | 40 | 200 | 10 | 200 | 40 | 300 | 30 | 40 400 | 50 | 40 400 | 50 | 40 500 | 30 | 30 500 | 30 | 30 600 | 30 | 50 700 | 40 | 30 800 | 40 | 30 (12 rows) select pn,vn,max(vn) over (order by pn range between 200 preceding and 0 preceding) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 40 100 | 40 | 40 200 | 10 | 40 200 | 40 | 40 300 | 30 | 40 400 | 50 | 50 400 | 50 | 50 500 | 30 | 50 500 | 30 | 50 600 | 30 | 50 700 | 40 | 40 800 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn range between 200 preceding and 150 following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 40 100 | 40 | 40 200 | 10 | 40 200 | 40 | 40 300 | 30 | 50 400 | 50 | 50 400 | 50 | 50 500 | 30 | 50 500 | 30 | 50 600 | 30 | 50 700 | 40 | 40 800 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn range between 0 preceding and 150 following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 40 100 | 40 | 40 200 | 10 | 40 200 | 40 | 40 300 | 30 | 50 400 | 50 | 50 400 | 50 | 50 500 | 30 | 30 500 | 30 | 30 600 | 30 | 40 700 | 40 | 40 800 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn range between 0 following and 150 following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 40 100 | 40 | 40 200 | 10 | 40 200 | 40 | 40 300 | 30 | 50 400 | 50 | 50 400 | 50 | 50 500 | 30 | 30 500 | 30 | 30 600 | 30 | 40 700 | 40 | 40 800 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn range between 150 following and 200 following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 30 100 | 40 | 30 200 | 10 | 50 200 | 40 | 50 300 | 30 | 30 400 | 50 | 30 400 | 50 | 30 500 | 30 | 40 500 | 30 | 40 600 | 30 | 40 700 | 40 | 800 | 40 | (12 rows) select pn,vn,max(vn) over (order by pn range between unbounded preceding and 200 preceding) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 100 | 40 | 200 | 10 | 200 | 40 | 300 | 30 | 40 400 | 50 | 40 400 | 50 | 40 500 | 30 | 40 500 | 30 | 40 600 | 30 | 50 700 | 40 | 50 800 | 40 | 50 (12 rows) select pn,vn,max(vn) over (order by pn range between unbounded preceding and 0 preceding) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 40 100 | 40 | 40 200 | 10 | 40 200 | 40 | 40 300 | 30 | 40 400 | 50 | 50 400 | 50 | 50 500 | 30 | 50 500 | 30 | 50 600 | 30 | 50 700 | 40 | 50 800 | 40 | 50 (12 rows) select pn,vn,max(vn) over (order by pn range between unbounded preceding and 200 following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 40 100 | 40 | 40 200 | 10 | 50 200 | 40 | 50 300 | 30 | 50 400 | 50 | 50 400 | 50 | 50 500 | 30 | 50 500 | 30 | 50 600 | 30 | 50 700 | 40 | 50 800 | 40 | 50 (12 rows) select pn,vn,max(vn) over (order by pn range between 200 preceding and unbounded following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 50 100 | 40 | 50 200 | 10 | 50 200 | 40 | 50 300 | 30 | 50 400 | 50 | 50 400 | 50 | 50 500 | 30 | 50 500 | 30 | 50 600 | 30 | 50 700 | 40 | 40 800 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn range between 0 preceding and unbounded following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 50 100 | 40 | 50 200 | 10 | 50 200 | 40 | 50 300 | 30 | 50 400 | 50 | 50 400 | 50 | 50 500 | 30 | 40 500 | 30 | 40 600 | 30 | 40 700 | 40 | 40 800 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn range between 0 following and unbounded following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 50 100 | 40 | 50 200 | 10 | 50 200 | 40 | 50 300 | 30 | 50 400 | 50 | 50 400 | 50 | 50 500 | 30 | 40 500 | 30 | 40 600 | 30 | 40 700 | 40 | 40 800 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn range between 150 following and unbounded following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 50 100 | 40 | 50 200 | 10 | 50 200 | 40 | 50 300 | 30 | 40 400 | 50 | 40 400 | 50 | 40 500 | 30 | 40 500 | 30 | 40 600 | 30 | 40 700 | 40 | 800 | 40 | (12 rows) select pn,vn,max(vn) over (order by pn range between unbounded preceding and unbounded following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 100 | 20 | 50 100 | 40 | 50 200 | 10 | 50 200 | 40 | 50 300 | 30 | 50 400 | 50 | 50 400 | 50 | 50 500 | 30 | 50 500 | 30 | 50 600 | 30 | 50 700 | 40 | 50 800 | 40 | 50 (12 rows) select pn,vn,max(vn) over (order by pn desc range between 200 preceding and 150 preceding) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 700 | 40 | 600 | 30 | 40 500 | 30 | 40 500 | 30 | 40 400 | 50 | 30 400 | 50 | 30 300 | 30 | 30 200 | 40 | 50 200 | 10 | 50 100 | 20 | 30 100 | 40 | 30 (12 rows) select pn,vn,max(vn) over (order by pn desc range between 200 preceding and 0 preceding) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 40 700 | 40 | 40 600 | 30 | 40 500 | 30 | 40 500 | 30 | 40 400 | 50 | 50 400 | 50 | 50 300 | 30 | 50 200 | 40 | 50 200 | 10 | 50 100 | 20 | 40 100 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn desc range between 200 preceding and 150 following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 40 700 | 40 | 40 600 | 30 | 40 500 | 30 | 50 500 | 30 | 50 400 | 50 | 50 400 | 50 | 50 300 | 30 | 50 200 | 40 | 50 200 | 10 | 50 100 | 20 | 40 100 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn desc range between 0 preceding and 150 following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 40 700 | 40 | 40 600 | 30 | 30 500 | 30 | 50 500 | 30 | 50 400 | 50 | 50 400 | 50 | 50 300 | 30 | 40 200 | 40 | 40 200 | 10 | 40 100 | 20 | 40 100 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn desc range between 0 following and 150 following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 40 700 | 40 | 40 600 | 30 | 30 500 | 30 | 50 500 | 30 | 50 400 | 50 | 50 400 | 50 | 50 300 | 30 | 40 200 | 40 | 40 200 | 10 | 40 100 | 20 | 40 100 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn desc range between 150 following and 200 following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 30 700 | 40 | 30 600 | 30 | 50 500 | 30 | 30 500 | 30 | 30 400 | 50 | 40 400 | 50 | 40 300 | 30 | 40 200 | 40 | 200 | 10 | 100 | 20 | 100 | 40 | (12 rows) select pn,vn,max(vn) over (order by pn desc range between unbounded preceding and 200 preceding) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 700 | 40 | 600 | 30 | 40 500 | 30 | 40 500 | 30 | 40 400 | 50 | 40 400 | 50 | 40 300 | 30 | 40 200 | 40 | 50 200 | 10 | 50 100 | 20 | 50 100 | 40 | 50 (12 rows) select pn,vn,max(vn) over (order by pn desc range between unbounded preceding and 0 preceding) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 40 700 | 40 | 40 600 | 30 | 40 500 | 30 | 40 500 | 30 | 40 400 | 50 | 50 400 | 50 | 50 300 | 30 | 50 200 | 40 | 50 200 | 10 | 50 100 | 20 | 50 100 | 40 | 50 (12 rows) select pn,vn,max(vn) over (order by pn desc range between unbounded preceding and 200 following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 40 700 | 40 | 40 600 | 30 | 50 500 | 30 | 50 500 | 30 | 50 400 | 50 | 50 400 | 50 | 50 300 | 30 | 50 200 | 40 | 50 200 | 10 | 50 100 | 20 | 50 100 | 40 | 50 (12 rows) select pn,vn,max(vn) over (order by pn desc range between 200 preceding and unbounded following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 50 700 | 40 | 50 600 | 30 | 50 500 | 30 | 50 500 | 30 | 50 400 | 50 | 50 400 | 50 | 50 300 | 30 | 50 200 | 40 | 50 200 | 10 | 50 100 | 20 | 40 100 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn desc range between 0 preceding and unbounded following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 50 700 | 40 | 50 600 | 30 | 50 500 | 30 | 50 500 | 30 | 50 400 | 50 | 50 400 | 50 | 50 300 | 30 | 40 200 | 40 | 40 200 | 10 | 40 100 | 20 | 40 100 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn desc range between 0 following and unbounded following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 50 700 | 40 | 50 600 | 30 | 50 500 | 30 | 50 500 | 30 | 50 400 | 50 | 50 400 | 50 | 50 300 | 30 | 40 200 | 40 | 40 200 | 10 | 40 100 | 20 | 40 100 | 40 | 40 (12 rows) select pn,vn,max(vn) over (order by pn desc range between 150 following and unbounded following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 50 700 | 40 | 50 600 | 30 | 50 500 | 30 | 40 500 | 30 | 40 400 | 50 | 40 400 | 50 | 40 300 | 30 | 40 200 | 40 | 200 | 10 | 100 | 20 | 100 | 40 | (12 rows) select pn,vn,max(vn) over (order by pn desc range between unbounded preceding and unbounded following) as max from sale; --mvd 1->3 pn | vn | max -----+----+----- 800 | 40 | 50 700 | 40 | 50 600 | 30 | 50 500 | 30 | 50 500 | 30 | 50 400 | 50 | 50 400 | 50 | 50 300 | 30 | 50 200 | 40 | 50 200 | 10 | 50 100 | 20 | 50 100 | 40 | 50 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between 2 preceding and 1 preceding) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 1 | 20 | 100 | 1 | 10 | 200 | 20 1 | 30 | 300 | 10 1 | 50 | 400 | 10 1 | 30 | 500 | 30 3 | 40 | 200 | 3 | 30 | 500 | 40 3 | 30 | 600 | 30 2 | 40 | 100 | 2 | 50 | 400 | 40 4 | 40 | 700 | 4 | 40 | 800 | 40 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between 2 preceding and 0 preceding) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 1 | 20 | 100 | 20 1 | 10 | 200 | 10 1 | 30 | 300 | 10 1 | 50 | 400 | 10 1 | 30 | 500 | 30 3 | 40 | 200 | 40 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 40 2 | 50 | 400 | 40 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between 2 preceding and 1 following) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 1 | 20 | 100 | 10 1 | 10 | 200 | 10 1 | 30 | 300 | 10 1 | 50 | 400 | 10 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 40 2 | 50 | 400 | 40 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between 0 preceding and 1 following) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 2 | 40 | 100 | 40 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 1 | 20 | 100 | 10 1 | 10 | 200 | 10 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between 0 following and 1 following) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 2 | 40 | 100 | 40 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 1 | 20 | 100 | 10 1 | 10 | 200 | 10 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between 1 following and 2 following) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 1 | 20 | 100 | 10 1 | 10 | 200 | 30 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 2 | 40 | 100 | 50 2 | 50 | 400 | 4 | 40 | 700 | 40 4 | 40 | 800 | (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between unbounded preceding and 2 preceding) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 2 | 40 | 100 | 2 | 50 | 400 | 4 | 40 | 700 | 4 | 40 | 800 | 1 | 20 | 100 | 1 | 10 | 200 | 1 | 30 | 300 | 20 1 | 50 | 400 | 10 1 | 30 | 500 | 10 3 | 40 | 200 | 3 | 30 | 500 | 3 | 30 | 600 | 40 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between unbounded preceding and 0 preceding) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 2 | 40 | 100 | 40 2 | 50 | 400 | 40 4 | 40 | 700 | 40 4 | 40 | 800 | 40 1 | 20 | 100 | 20 1 | 10 | 200 | 10 1 | 30 | 300 | 10 1 | 50 | 400 | 10 1 | 30 | 500 | 10 3 | 40 | 200 | 40 3 | 30 | 500 | 30 3 | 30 | 600 | 30 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between unbounded preceding and 2 following) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 2 | 40 | 100 | 40 2 | 50 | 400 | 40 4 | 40 | 700 | 40 4 | 40 | 800 | 40 1 | 20 | 100 | 10 1 | 10 | 200 | 10 1 | 30 | 300 | 10 1 | 50 | 400 | 10 1 | 30 | 500 | 10 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between 2 preceding and unbounded following) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 2 | 40 | 100 | 40 2 | 50 | 400 | 40 4 | 40 | 700 | 40 4 | 40 | 800 | 40 1 | 20 | 100 | 10 1 | 10 | 200 | 10 1 | 30 | 300 | 10 1 | 50 | 400 | 10 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between 0 preceding and unbounded following) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 1 | 20 | 100 | 10 1 | 10 | 200 | 10 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 40 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between 0 following and unbounded following) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 1 | 20 | 100 | 10 1 | 10 | 200 | 10 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 40 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between 1 following and unbounded following) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 2 | 40 | 100 | 50 2 | 50 | 400 | 4 | 40 | 700 | 40 4 | 40 | 800 | 1 | 20 | 100 | 10 1 | 10 | 200 | 30 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | (12 rows) select cn,vn,pn,min(vn) over (partition by cn order by pn rows between unbounded preceding and unbounded following) as min from sale; --mvd 1->4 cn | vn | pn | min ----+----+-----+----- 1 | 20 | 100 | 10 1 | 10 | 200 | 10 1 | 30 | 300 | 10 1 | 50 | 400 | 10 1 | 30 | 500 | 10 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 40 2 | 50 | 400 | 40 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between 200 preceding and 150 preceding) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 1 | 200 | 10 | 1 | 300 | 30 | 20 1 | 400 | 50 | 10 1 | 500 | 30 | 30 3 | 200 | 40 | 3 | 500 | 30 | 3 | 600 | 30 | 2 | 100 | 40 | 2 | 400 | 50 | 4 | 700 | 40 | 4 | 800 | 40 | (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between 200 preceding and 0 preceding) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 20 1 | 200 | 10 | 20 1 | 300 | 30 | 30 1 | 400 | 50 | 50 1 | 500 | 30 | 50 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between 200 preceding and 150 following) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 1 | 100 | 20 | 20 1 | 200 | 10 | 30 1 | 300 | 30 | 50 1 | 400 | 50 | 50 1 | 500 | 30 | 50 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between 0 preceding and 150 following) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 20 1 | 200 | 10 | 30 1 | 300 | 30 | 50 1 | 400 | 50 | 50 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between 0 following and 150 following) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 20 1 | 200 | 10 | 30 1 | 300 | 30 | 50 1 | 400 | 50 | 50 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between 150 following and 200 following) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 30 1 | 200 | 10 | 50 1 | 300 | 30 | 30 1 | 400 | 50 | 1 | 500 | 30 | 3 | 200 | 40 | 3 | 500 | 30 | 3 | 600 | 30 | 2 | 100 | 40 | 2 | 400 | 50 | 4 | 700 | 40 | 4 | 800 | 40 | (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between unbounded preceding and 200 preceding) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 1 | 200 | 10 | 1 | 300 | 30 | 20 1 | 400 | 50 | 20 1 | 500 | 30 | 30 3 | 200 | 40 | 3 | 500 | 30 | 40 3 | 600 | 30 | 40 2 | 100 | 40 | 2 | 400 | 50 | 40 4 | 700 | 40 | 4 | 800 | 40 | (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between unbounded preceding and 0 preceding) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 1 | 100 | 20 | 20 1 | 200 | 10 | 20 1 | 300 | 30 | 30 1 | 400 | 50 | 50 1 | 500 | 30 | 50 3 | 200 | 40 | 40 3 | 500 | 30 | 40 3 | 600 | 30 | 40 (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between unbounded preceding and 200 following) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 30 1 | 200 | 10 | 50 1 | 300 | 30 | 50 1 | 400 | 50 | 50 1 | 500 | 30 | 50 3 | 200 | 40 | 40 3 | 500 | 30 | 40 3 | 600 | 30 | 40 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between 200 preceding and unbounded following) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 50 1 | 200 | 10 | 50 1 | 300 | 30 | 50 1 | 400 | 50 | 50 1 | 500 | 30 | 50 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 50 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between 0 preceding and unbounded following) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 2 | 100 | 40 | 50 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 1 | 100 | 20 | 50 1 | 200 | 10 | 50 1 | 300 | 30 | 50 1 | 400 | 50 | 50 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between 0 following and unbounded following) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 50 1 | 200 | 10 | 50 1 | 300 | 30 | 50 1 | 400 | 50 | 50 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 50 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between 150 following and unbounded following) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 2 | 100 | 40 | 50 2 | 400 | 50 | 4 | 700 | 40 | 4 | 800 | 40 | 1 | 100 | 20 | 50 1 | 200 | 10 | 50 1 | 300 | 30 | 30 1 | 400 | 50 | 1 | 500 | 30 | 3 | 200 | 40 | 30 3 | 500 | 30 | 3 | 600 | 30 | (12 rows) select cn,pn,vn,max(vn) over (partition by cn order by pn range between unbounded preceding and unbounded following) as max from sale; --mvd 1,2->4 cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 50 1 | 200 | 10 | 50 1 | 300 | 30 | 50 1 | 400 | 50 | 50 1 | 500 | 30 | 50 3 | 200 | 40 | 40 3 | 500 | 30 | 40 3 | 600 | 30 | 40 2 | 100 | 40 | 50 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) -- MPP-1943 SELECT sale.cn,sale.pn,sale.vn, MAX(floor(sale.pn/sale.vn)) OVER(order by sale.cn asc,sale.cn asc,sale.pn asc) FROM sale; cn | pn | vn | max ----+-----+----+----- 1 | 100 | 20 | 5 1 | 200 | 10 | 20 1 | 300 | 30 | 20 1 | 400 | 50 | 20 1 | 500 | 30 | 20 2 | 100 | 40 | 20 2 | 400 | 50 | 20 3 | 200 | 40 | 20 3 | 500 | 30 | 20 3 | 600 | 30 | 20 4 | 700 | 40 | 20 4 | 800 | 40 | 20 (12 rows) -- MPP-1944 SELECT sale.pn,cn,dt,pn,prc, MAX(floor(sale.prc+sale.prc)) OVER(partition by sale.pn,sale.cn,sale.dt,sale.pn order by sale.pn desc,sale.pn asc rows between current row and unbounded following ) FROM sale; --mvd 1,2,3->6 pn | cn | dt | pn | prc | max -----+----+------------+-----+------+------ 100 | 1 | 05-01-1401 | 100 | 0 | 0 200 | 3 | 04-01-1401 | 200 | 0 | 0 300 | 1 | 05-02-1401 | 300 | 0 | 0 400 | 1 | 06-01-1401 | 400 | 0 | 0 500 | 1 | 06-01-1401 | 500 | 5 | 10 500 | 3 | 06-01-1401 | 500 | 5 | 10 700 | 4 | 06-01-1401 | 700 | 1 | 2 100 | 2 | 01-01-1401 | 100 | 2400 | 4800 200 | 1 | 03-01-1401 | 200 | 0 | 0 400 | 2 | 06-01-1401 | 400 | 0 | 0 600 | 3 | 06-01-1401 | 600 | 5 | 10 800 | 4 | 06-01-1401 | 800 | 1 | 2 (12 rows) select qty,cn,pn,dt,pn,prc, MAX(floor(sale.prc+sale.prc)) OVER(partition by sale.qty,sale.cn,sale.pn,sale.dt order by sale.pn asc range between 0 following and unbounded following ) from sale; --mvd 1,2,3,4->7 qty | cn | pn | dt | pn | prc | max ------+----+-----+------------+-----+------+------ 1 | 1 | 200 | 03-01-1401 | 200 | 0 | 0 1 | 2 | 400 | 06-01-1401 | 400 | 0 | 0 1 | 4 | 800 | 06-01-1401 | 800 | 1 | 2 12 | 1 | 500 | 06-01-1401 | 500 | 5 | 10 12 | 3 | 500 | 06-01-1401 | 500 | 5 | 10 1 | 1 | 100 | 05-01-1401 | 100 | 0 | 0 1 | 1 | 300 | 05-02-1401 | 300 | 0 | 0 1 | 1 | 400 | 06-01-1401 | 400 | 0 | 0 1 | 3 | 200 | 04-01-1401 | 200 | 0 | 0 1 | 4 | 700 | 06-01-1401 | 700 | 1 | 2 12 | 3 | 600 | 06-01-1401 | 600 | 5 | 10 1100 | 2 | 100 | 01-01-1401 | 100 | 2400 | 4800 (12 rows) -- MPP-1947 SELECT dt,cn,cn,qty, MIN(floor(sale.qty)) OVER(partition by sale.dt,sale.cn,sale.dt order by sale.cn desc range between 1 preceding and unbounded following ) FROM sale; --mvd 1,2->5 dt | cn | cn | qty | min ------------+----+----+------+------ 04-01-1401 | 3 | 3 | 1 | 1 05-01-1401 | 1 | 1 | 1 | 1 06-01-1401 | 2 | 2 | 1 | 1 06-01-1401 | 4 | 4 | 1 | 1 06-01-1401 | 4 | 4 | 1 | 1 01-01-1401 | 2 | 2 | 1100 | 1100 03-01-1401 | 1 | 1 | 1 | 1 05-02-1401 | 1 | 1 | 1 | 1 06-01-1401 | 1 | 1 | 1 | 1 06-01-1401 | 1 | 1 | 12 | 1 06-01-1401 | 3 | 3 | 12 | 12 06-01-1401 | 3 | 3 | 12 | 12 (12 rows) SELECT dt,cn,cn,qty, MAX(floor(sale.qty)) OVER(partition by sale.dt,sale.cn,sale.dt order by sale.cn desc range between 1 preceding and unbounded following ) from sale; --mvd 1,2->5 dt | cn | cn | qty | max ------------+----+----+------+------ 04-01-1401 | 3 | 3 | 1 | 1 05-01-1401 | 1 | 1 | 1 | 1 06-01-1401 | 2 | 2 | 1 | 1 06-01-1401 | 4 | 4 | 1 | 1 06-01-1401 | 4 | 4 | 1 | 1 01-01-1401 | 2 | 2 | 1100 | 1100 03-01-1401 | 1 | 1 | 1 | 1 05-02-1401 | 1 | 1 | 1 | 1 06-01-1401 | 1 | 1 | 12 | 12 06-01-1401 | 1 | 1 | 1 | 12 06-01-1401 | 3 | 3 | 12 | 12 06-01-1401 | 3 | 3 | 12 | 12 (12 rows) -- FIRST_VALUE/LAST_VALUE select cn,vn,first_value(vn) over (order by ord,cn rows between 2 preceding and 1 preceding) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 1 | 10 | 40 3 | 40 | 40 1 | 20 | 10 1 | 30 | 40 1 | 50 | 20 2 | 50 | 30 1 | 30 | 50 3 | 30 | 50 3 | 30 | 30 4 | 40 | 30 4 | 40 | 30 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between 2 preceding and 0 preceding) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 40 1 | 10 | 40 3 | 40 | 40 1 | 20 | 10 1 | 30 | 40 1 | 50 | 20 2 | 50 | 30 1 | 30 | 50 3 | 30 | 50 3 | 30 | 30 4 | 40 | 30 4 | 40 | 30 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between 2 preceding and 1 following) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 40 1 | 10 | 40 3 | 40 | 40 1 | 20 | 10 1 | 30 | 40 1 | 50 | 20 2 | 50 | 30 1 | 30 | 50 3 | 30 | 50 3 | 30 | 30 4 | 40 | 30 4 | 40 | 30 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between 0 preceding and 1 following) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 40 1 | 10 | 10 3 | 40 | 40 1 | 20 | 20 1 | 30 | 30 1 | 50 | 50 2 | 50 | 50 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between 0 following and 1 following) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 40 1 | 10 | 10 3 | 40 | 40 1 | 20 | 20 1 | 30 | 30 1 | 50 | 50 2 | 50 | 50 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between 1 following and 2 following) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 10 1 | 10 | 40 3 | 40 | 20 1 | 20 | 30 1 | 30 | 50 1 | 50 | 50 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 40 4 | 40 | 40 4 | 40 | (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between unbounded preceding and 2 preceding) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 1 | 10 | 3 | 40 | 40 1 | 20 | 40 1 | 30 | 40 1 | 50 | 40 2 | 50 | 40 1 | 30 | 40 3 | 30 | 40 3 | 30 | 40 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between unbounded preceding and 0 preceding) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 40 1 | 10 | 40 3 | 40 | 40 1 | 20 | 40 1 | 30 | 40 1 | 50 | 40 2 | 50 | 40 1 | 30 | 40 3 | 30 | 40 3 | 30 | 40 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between unbounded preceding and 2 following) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 40 1 | 10 | 40 3 | 40 | 40 1 | 20 | 40 1 | 30 | 40 1 | 50 | 40 2 | 50 | 40 1 | 30 | 40 3 | 30 | 40 3 | 30 | 40 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between 2 preceding and unbounded following) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 40 1 | 10 | 40 3 | 40 | 40 1 | 20 | 10 1 | 30 | 40 1 | 50 | 20 2 | 50 | 30 1 | 30 | 50 3 | 30 | 50 3 | 30 | 30 4 | 40 | 30 4 | 40 | 30 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between 0 preceding and unbounded following) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 40 1 | 10 | 10 3 | 40 | 40 1 | 20 | 20 1 | 30 | 30 1 | 50 | 50 2 | 50 | 50 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between 0 following and unbounded following) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 40 1 | 10 | 10 3 | 40 | 40 1 | 20 | 20 1 | 30 | 30 1 | 50 | 50 2 | 50 | 50 1 | 30 | 30 3 | 30 | 30 3 | 30 | 30 4 | 40 | 40 4 | 40 | 40 (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between 1 following and unbounded following) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 10 1 | 10 | 40 3 | 40 | 20 1 | 20 | 30 1 | 30 | 50 1 | 50 | 50 2 | 50 | 30 1 | 30 | 30 3 | 30 | 30 3 | 30 | 40 4 | 40 | 40 4 | 40 | (12 rows) select cn,vn,first_value(vn) over (order by ord,cn rows between unbounded preceding and unbounded following) as first_value from sale_ord; cn | vn | first_value ----+----+------------- 2 | 40 | 40 1 | 10 | 40 3 | 40 | 40 1 | 20 | 40 1 | 30 | 40 1 | 50 | 40 2 | 50 | 40 1 | 30 | 40 3 | 30 | 40 3 | 30 | 40 4 | 40 | 40 4 | 40 | 40 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between 200 preceding and 150 preceding) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 700 | 40 | 600 | 30 | 8 500 | 30 | 7 500 | 30 | 7 400 | 50 | 6 400 | 50 | 6 300 | 30 | 5 200 | 40 | 4 200 | 10 | 4 100 | 20 | 3 100 | 40 | 3 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between 200 preceding and 0 preceding) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 8 700 | 40 | 7 600 | 30 | 6 500 | 30 | 5 500 | 30 | 5 400 | 50 | 4 400 | 50 | 4 300 | 30 | 3 200 | 40 | 2 200 | 10 | 2 100 | 20 | 1 100 | 40 | 1 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between 200 preceding and 150 following) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 7 700 | 40 | 6 600 | 30 | 5 500 | 30 | 4 500 | 30 | 4 400 | 50 | 3 400 | 50 | 3 300 | 30 | 2 200 | 40 | 1 200 | 10 | 1 100 | 20 | 1 100 | 40 | 1 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between 0 preceding and 150 following) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 7 700 | 40 | 6 600 | 30 | 5 500 | 30 | 4 500 | 30 | 4 400 | 50 | 3 400 | 50 | 3 300 | 30 | 2 200 | 40 | 1 200 | 10 | 1 100 | 20 | 1 100 | 40 | 1 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between 0 following and 150 following) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 7 700 | 40 | 6 600 | 30 | 5 500 | 30 | 4 500 | 30 | 4 400 | 50 | 3 400 | 50 | 3 300 | 30 | 2 200 | 40 | 1 200 | 10 | 1 100 | 20 | 1 100 | 40 | 1 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between 150 following and 200 following) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 6 700 | 40 | 5 600 | 30 | 4 500 | 30 | 3 500 | 30 | 3 400 | 50 | 2 400 | 50 | 2 300 | 30 | 1 200 | 40 | 200 | 10 | 100 | 20 | 100 | 40 | (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between unbounded preceding and 200 preceding) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 700 | 40 | 600 | 30 | 8 500 | 30 | 7 500 | 30 | 7 400 | 50 | 6 400 | 50 | 6 300 | 30 | 5 200 | 40 | 4 200 | 10 | 4 100 | 20 | 3 100 | 40 | 3 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between unbounded preceding and 0 preceding) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 8 700 | 40 | 7 600 | 30 | 6 500 | 30 | 5 500 | 30 | 5 400 | 50 | 4 400 | 50 | 4 300 | 30 | 3 200 | 40 | 2 200 | 10 | 2 100 | 20 | 1 100 | 40 | 1 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between unbounded preceding and 200 following) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 6 700 | 40 | 5 600 | 30 | 4 500 | 30 | 3 500 | 30 | 3 400 | 50 | 2 400 | 50 | 2 300 | 30 | 1 200 | 40 | 1 200 | 10 | 1 100 | 20 | 1 100 | 40 | 1 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between 200 preceding and unbounded following) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 1 700 | 40 | 1 600 | 30 | 1 500 | 30 | 1 500 | 30 | 1 400 | 50 | 1 400 | 50 | 1 300 | 30 | 1 200 | 40 | 1 200 | 10 | 1 100 | 20 | 1 100 | 40 | 1 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between 0 preceding and unbounded following) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 1 700 | 40 | 1 600 | 30 | 1 500 | 30 | 1 500 | 30 | 1 400 | 50 | 1 400 | 50 | 1 300 | 30 | 1 200 | 40 | 1 200 | 10 | 1 100 | 20 | 1 100 | 40 | 1 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between 0 following and unbounded following) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 1 700 | 40 | 1 600 | 30 | 1 500 | 30 | 1 500 | 30 | 1 400 | 50 | 1 400 | 50 | 1 300 | 30 | 1 200 | 40 | 1 200 | 10 | 1 100 | 20 | 1 100 | 40 | 1 (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between 150 following and unbounded following) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 1 700 | 40 | 1 600 | 30 | 1 500 | 30 | 1 500 | 30 | 1 400 | 50 | 1 400 | 50 | 1 300 | 30 | 1 200 | 40 | 200 | 10 | 100 | 20 | 100 | 40 | (12 rows) select pn,vn,last_value((pn+vn)/100) over (order by pn desc range between unbounded preceding and unbounded following) as last_value from sale;--mvd 1->3 pn | vn | last_value -----+----+------------ 800 | 40 | 1 700 | 40 | 1 600 | 30 | 1 500 | 30 | 1 500 | 30 | 1 400 | 50 | 1 400 | 50 | 1 300 | 30 | 1 200 | 40 | 1 200 | 10 | 1 100 | 20 | 1 100 | 40 | 1 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between 2 preceding and 1 preceding) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 2 | 40 | 100 | 2 | 50 | 400 | 40 4 | 40 | 700 | 4 | 40 | 800 | 40 1 | 20 | 100 | 1 | 10 | 200 | 20 1 | 30 | 300 | 10 1 | 50 | 400 | 30 1 | 30 | 500 | 50 3 | 40 | 200 | 3 | 30 | 500 | 40 3 | 30 | 600 | 30 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between 2 preceding and 0 preceding) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 2 | 40 | 100 | 40 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 1 | 20 | 100 | 20 1 | 10 | 200 | 10 1 | 30 | 300 | 30 1 | 50 | 400 | 50 1 | 30 | 500 | 30 3 | 40 | 200 | 40 3 | 30 | 500 | 30 3 | 30 | 600 | 30 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between 2 preceding and 1 following) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 1 | 20 | 100 | 10 1 | 10 | 200 | 30 1 | 30 | 300 | 50 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 50 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between 0 preceding and 1 following) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 2 | 40 | 100 | 50 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 1 | 20 | 100 | 10 1 | 10 | 200 | 30 1 | 30 | 300 | 50 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between 0 following and 1 following) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 2 | 40 | 100 | 50 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 1 | 20 | 100 | 10 1 | 10 | 200 | 30 1 | 30 | 300 | 50 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between 1 following and 2 following) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 1 | 20 | 100 | 30 1 | 10 | 200 | 50 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 2 | 40 | 100 | 50 2 | 50 | 400 | 4 | 40 | 700 | 40 4 | 40 | 800 | (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between unbounded preceding and 2 preceding) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 1 | 20 | 100 | 1 | 10 | 200 | 1 | 30 | 300 | 20 1 | 50 | 400 | 10 1 | 30 | 500 | 30 3 | 40 | 200 | 3 | 30 | 500 | 3 | 30 | 600 | 40 2 | 40 | 100 | 2 | 50 | 400 | 4 | 40 | 700 | 4 | 40 | 800 | (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between unbounded preceding and 0 preceding) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 2 | 40 | 100 | 40 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 1 | 20 | 100 | 20 1 | 10 | 200 | 10 1 | 30 | 300 | 30 1 | 50 | 400 | 50 1 | 30 | 500 | 30 3 | 40 | 200 | 40 3 | 30 | 500 | 30 3 | 30 | 600 | 30 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between unbounded preceding and 2 following) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 1 | 20 | 100 | 30 1 | 10 | 200 | 50 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 50 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between 2 preceding and unbounded following) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 1 | 20 | 100 | 30 1 | 10 | 200 | 30 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 50 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between 0 preceding and unbounded following) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 1 | 20 | 100 | 30 1 | 10 | 200 | 30 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 50 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between 0 following and unbounded following) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 1 | 20 | 100 | 30 1 | 10 | 200 | 30 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 50 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between 1 following and unbounded following) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 1 | 20 | 100 | 30 1 | 10 | 200 | 30 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 2 | 40 | 100 | 50 2 | 50 | 400 | 4 | 40 | 700 | 40 4 | 40 | 800 | (12 rows) select cn,vn,pn,last_value(vn) over (partition by cn order by pn rows between unbounded preceding and unbounded following) as last_value from sale; --mvd 1->4 cn | vn | pn | last_value ----+----+-----+------------ 1 | 20 | 100 | 30 1 | 10 | 200 | 30 1 | 30 | 300 | 30 1 | 50 | 400 | 30 1 | 30 | 500 | 30 3 | 40 | 200 | 30 3 | 30 | 500 | 30 3 | 30 | 600 | 30 2 | 40 | 100 | 50 2 | 50 | 400 | 50 4 | 40 | 700 | 40 4 | 40 | 800 | 40 (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between 200 preceding and 150 preceding) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 1 | 200 | 10 | 1 | 300 | 30 | 20 1 | 400 | 50 | 10 1 | 500 | 30 | 30 3 | 200 | 40 | 3 | 500 | 30 | 3 | 600 | 30 | 2 | 100 | 40 | 2 | 400 | 50 | 4 | 700 | 40 | 4 | 800 | 40 | (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between 200 preceding and 0 preceding) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 20 1 | 200 | 10 | 20 1 | 300 | 30 | 20 1 | 400 | 50 | 10 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between 200 preceding and 150 following) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 20 1 | 200 | 10 | 20 1 | 300 | 30 | 20 1 | 400 | 50 | 10 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between 0 preceding and 150 following) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 20 1 | 200 | 10 | 10 1 | 300 | 30 | 30 1 | 400 | 50 | 50 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between 0 following and 150 following) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 20 1 | 200 | 10 | 10 1 | 300 | 30 | 30 1 | 400 | 50 | 50 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between 150 following and 200 following) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 30 1 | 200 | 10 | 50 1 | 300 | 30 | 30 1 | 400 | 50 | 1 | 500 | 30 | 3 | 200 | 40 | 3 | 500 | 30 | 3 | 600 | 30 | 2 | 100 | 40 | 2 | 400 | 50 | 4 | 700 | 40 | 4 | 800 | 40 | (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between unbounded preceding and 200 preceding) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 1 | 200 | 10 | 1 | 300 | 30 | 20 1 | 400 | 50 | 20 1 | 500 | 30 | 20 3 | 200 | 40 | 3 | 500 | 30 | 40 3 | 600 | 30 | 40 2 | 100 | 40 | 2 | 400 | 50 | 40 4 | 700 | 40 | 4 | 800 | 40 | (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between unbounded preceding and 0 preceding) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 2 | 100 | 40 | 40 2 | 400 | 50 | 40 4 | 700 | 40 | 40 4 | 800 | 40 | 40 1 | 100 | 20 | 20 1 | 200 | 10 | 20 1 | 300 | 30 | 20 1 | 400 | 50 | 20 1 | 500 | 30 | 20 3 | 200 | 40 | 40 3 | 500 | 30 | 40 3 | 600 | 30 | 40 (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between unbounded preceding and 200 following) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 20 1 | 200 | 10 | 20 1 | 300 | 30 | 20 1 | 400 | 50 | 20 1 | 500 | 30 | 20 3 | 200 | 40 | 40 3 | 500 | 30 | 40 3 | 600 | 30 | 40 2 | 100 | 40 | 40 2 | 400 | 50 | 40 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between 200 preceding and unbounded following) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 20 1 | 200 | 10 | 20 1 | 300 | 30 | 20 1 | 400 | 50 | 10 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between 0 preceding and unbounded following) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 1 | 100 | 20 | 20 1 | 200 | 10 | 10 1 | 300 | 30 | 30 1 | 400 | 50 | 50 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between 0 following and unbounded following) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 20 1 | 200 | 10 | 10 1 | 300 | 30 | 30 1 | 400 | 50 | 50 1 | 500 | 30 | 30 3 | 200 | 40 | 40 3 | 500 | 30 | 30 3 | 600 | 30 | 30 2 | 100 | 40 | 40 2 | 400 | 50 | 50 4 | 700 | 40 | 40 4 | 800 | 40 | 40 (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between 150 following and unbounded following) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 1 | 100 | 20 | 30 1 | 200 | 10 | 50 1 | 300 | 30 | 30 1 | 400 | 50 | 1 | 500 | 30 | 3 | 200 | 40 | 30 3 | 500 | 30 | 3 | 600 | 30 | 2 | 100 | 40 | 50 2 | 400 | 50 | 4 | 700 | 40 | 4 | 800 | 40 | (12 rows) select cn,pn,vn,first_value(vn) over (partition by cn order by pn range between unbounded preceding and unbounded following) as first_value from sale; --mvd 1->4 cn | pn | vn | first_value ----+-----+----+------------- 2 | 100 | 40 | 40 2 | 400 | 50 | 40 4 | 700 | 40 | 40 4 | 800 | 40 | 40 1 | 100 | 20 | 20 1 | 200 | 10 | 20 1 | 300 | 30 | 20 1 | 400 | 50 | 20 1 | 500 | 30 | 20 3 | 200 | 40 | 40 3 | 500 | 30 | 40 3 | 600 | 30 | 40 (12 rows) -- MPP-1957 select dt,pn,qty, LEAD(cast(floor(sale.qty/sale.qty) as int),cast (floor(sale.qty) as int),NULL) OVER(partition by sale.dt order by sale.pn asc) as lead from sale; --mvd 1->4 dt | pn | qty | lead ------------+-----+------+------ 01-01-1401 | 100 | 1100 | 04-01-1401 | 200 | 1 | 05-01-1401 | 100 | 1 | 03-01-1401 | 200 | 1 | 05-02-1401 | 300 | 1 | 06-01-1401 | 400 | 1 | 1 06-01-1401 | 400 | 1 | 1 06-01-1401 | 500 | 12 | 06-01-1401 | 500 | 12 | 06-01-1401 | 600 | 12 | 06-01-1401 | 700 | 1 | 1 06-01-1401 | 800 | 1 | (12 rows) -- MPP-1958 SELECT sale.qty, MIN(floor(sale.qty)) OVER(order by ord,sale.pn asc rows unbounded preceding ) as min,sale.pn, LAG(cast(floor(sale.qty-sale.prc) as int),cast (floor(sale.qty/sale.vn) as int),NULL) OVER(order by ord,sale.pn asc) as lag FROM sale_ord as sale; qty | min | pn | lag ------+------+-----+----- 1100 | 1100 | 100 | 1 | 1 | 200 | 1 1 | 1 | 200 | 1 1 | 1 | 100 | 1 1 | 1 | 300 | 1 1 | 1 | 400 | 1 1 | 1 | 400 | 1 12 | 1 | 500 | 7 12 | 1 | 500 | 7 12 | 1 | 600 | 7 1 | 1 | 700 | 0 1 | 1 | 800 | 0 (12 rows) -- MPP-1960 SELECT prc,cn,vn, FIRST_VALUE(floor(sale.prc)) OVER(partition by sale.prc,sale.cn order by sale.vn asc range between unbounded preceding and unbounded following) FROM sale; --mvd 1,2->4 prc | cn | vn | first_value ------+----+----+------------- 0 | 1 | 10 | 0 0 | 1 | 20 | 0 0 | 1 | 30 | 0 0 | 1 | 50 | 0 0 | 3 | 40 | 0 1 | 4 | 40 | 1 1 | 4 | 40 | 1 5 | 1 | 30 | 5 5 | 3 | 30 | 5 5 | 3 | 30 | 5 0 | 2 | 50 | 0 2400 | 2 | 40 | 2400 (12 rows) SELECT cn,pn,dt, FIRST_VALUE(floor(sale.pn/sale.pn)) OVER(partition by sale.cn,sale.pn,sale.dt order by sale.cn desc range between unbounded preceding and 1 following ) as fv from sale; --mvd 1,2,3->4 cn | pn | dt | fv ----+-----+------------+---- 1 | 100 | 05-01-1401 | 1 1 | 300 | 05-02-1401 | 1 1 | 400 | 06-01-1401 | 1 1 | 500 | 06-01-1401 | 1 3 | 200 | 04-01-1401 | 1 3 | 500 | 06-01-1401 | 1 4 | 700 | 06-01-1401 | 1 1 | 200 | 03-01-1401 | 1 2 | 100 | 01-01-1401 | 1 2 | 400 | 06-01-1401 | 1 3 | 600 | 06-01-1401 | 1 4 | 800 | 06-01-1401 | 1 (12 rows) -- MPP-1964 SELECT cn,(cn-prc),prc, CORR(floor(sale.cn-sale.prc),floor(sale.prc)) OVER(partition by sale.cn,sale.cn order by sale.cn desc range between 1 preceding and 1 following ) as corr FROM sale; --mvd 1->4 cn | ?column? | prc | corr ----+----------+------+------ 1 | 1 | 0 | -1 1 | -4 | 5 | -1 1 | 1 | 0 | -1 1 | 1 | 0 | -1 1 | 1 | 0 | -1 3 | -2 | 5 | -1 3 | -2 | 5 | -1 3 | 3 | 0 | -1 2 | 2 | 0 | -1 2 | -2398 | 2400 | -1 4 | 3 | 1 | 4 | 3 | 1 | (12 rows) SELECT cn,floor(qty/pn),cn, CORR(floor(sale.qty/sale.pn),floor(sale.cn)) OVER(order by sale.cn desc range 3 preceding) as correlation from sale; --mvd 1->4 cn | floor | cn | correlation ----+-------+----+--------------------- 4 | 0 | 4 | 4 | 0 | 4 | 3 | 0 | 3 | 3 | 0 | 3 | 3 | 0 | 3 | 2 | 0 | 2 | -0.540061724867322 2 | 11 | 2 | -0.540061724867322 1 | 0 | 1 | -0.0439799497133542 1 | 0 | 1 | -0.0439799497133542 1 | 0 | 1 | -0.0439799497133542 1 | 0 | 1 | -0.0439799497133542 1 | 0 | 1 | -0.0439799497133542 (12 rows) -- MPP-1976 SELECT sale.cn,sale.vn,sale.pn, SUM(floor(sale.cn*sale.vn)) OVER(partition by sale.vn,sale.pn order by sale.pn asc range between 1 following and unbounded following ) as sum from sale; --mvd 1,3->4 cn | vn | pn | sum ----+----+-----+----- 1 | 10 | 200 | 1 | 20 | 100 | 3 | 30 | 600 | 2 | 40 | 100 | 3 | 40 | 200 | 4 | 40 | 700 | 1 | 30 | 300 | 1 | 30 | 500 | 3 | 30 | 500 | 4 | 40 | 800 | 1 | 50 | 400 | 2 | 50 | 400 | (12 rows) -- Use expressions in the frame clause select cn,pn,qty,sum(qty) over (order by ord,pn rows cn preceding) from sale_ord; cn | pn | qty | sum ----+-----+------+------ 2 | 100 | 1100 | 1100 1 | 200 | 1 | 1101 3 | 200 | 1 | 1102 1 | 100 | 1 | 2 1 | 300 | 1 | 2 1 | 400 | 1 | 2 2 | 400 | 1 | 3 1 | 500 | 12 | 13 3 | 500 | 12 | 26 3 | 600 | 12 | 37 4 | 700 | 1 | 38 4 | 800 | 1 | 38 (12 rows) select cn,pn,qty,sum(qty) over (order by ord,pn rows between current row and cn following) from sale_ord; cn | pn | qty | sum ----+-----+------+------ 2 | 100 | 1100 | 1102 1 | 200 | 1 | 2 3 | 200 | 1 | 4 1 | 100 | 1 | 2 1 | 300 | 1 | 2 1 | 400 | 1 | 2 2 | 400 | 1 | 25 1 | 500 | 12 | 24 3 | 500 | 12 | 26 3 | 600 | 12 | 14 4 | 700 | 1 | 2 4 | 800 | 1 | 1 (12 rows) select cn,pn,qty,sum(qty) over (order by ord,pn rows between cn preceding and cn+2 following) from sale_ord; cn | pn | qty | sum ----+-----+------+------ 2 | 100 | 1100 | 1104 1 | 200 | 1 | 1104 3 | 200 | 1 | 1118 1 | 100 | 1 | 5 1 | 300 | 1 | 16 1 | 400 | 1 | 27 2 | 400 | 1 | 40 1 | 500 | 12 | 38 3 | 500 | 12 | 40 3 | 600 | 12 | 39 4 | 700 | 1 | 39 4 | 800 | 1 | 38 (12 rows) select cn,pn,qty,sum(qty) over (order by ord,pn rows between 1 preceding and 1 following), sum(qty) over (order by ord,pn rows between cn preceding and cn+2 following) from sale_ord; cn | pn | qty | sum | sum ----+-----+------+------+------ 2 | 100 | 1100 | 1101 | 1104 1 | 200 | 1 | 1102 | 1104 3 | 200 | 1 | 3 | 1118 1 | 100 | 1 | 3 | 5 1 | 300 | 1 | 3 | 16 1 | 400 | 1 | 3 | 27 2 | 400 | 1 | 14 | 40 1 | 500 | 12 | 25 | 38 3 | 500 | 12 | 36 | 40 3 | 600 | 12 | 25 | 39 4 | 700 | 1 | 14 | 39 4 | 800 | 1 | 2 | 38 (12 rows) select cn,pn,qty,sum(qty) over (order by ord,pn rows between current row and cn following), sum(qty) over (order by ord,pn rows between cn preceding and cn+2 following) from sale_ord; cn | pn | qty | sum | sum ----+-----+------+------+------ 2 | 100 | 1100 | 1102 | 1104 1 | 200 | 1 | 2 | 1104 3 | 200 | 1 | 4 | 1118 1 | 100 | 1 | 2 | 5 1 | 300 | 1 | 2 | 16 1 | 400 | 1 | 2 | 27 2 | 400 | 1 | 25 | 40 1 | 500 | 12 | 24 | 38 3 | 500 | 12 | 26 | 40 3 | 600 | 12 | 14 | 39 4 | 700 | 1 | 2 | 39 4 | 800 | 1 | 1 | 38 (12 rows) select cn,pn,qty,sum(qty) over (order by pn range cn preceding) from sale; --mvd 2->4 cn | pn | qty | sum ----+-----+------+------ 1 | 100 | 1 | 1101 2 | 100 | 1100 | 1101 1 | 200 | 1 | 2 3 | 200 | 1 | 2 1 | 300 | 1 | 1 1 | 400 | 1 | 2 2 | 400 | 1 | 2 1 | 500 | 12 | 24 3 | 500 | 12 | 24 3 | 600 | 12 | 12 4 | 700 | 1 | 1 4 | 800 | 1 | 1 (12 rows) select cn,pn,qty,sum(qty) over (order by pn range between current row and cn following) from sale; --mvd 2->4 cn | pn | qty | sum ----+-----+------+------ 1 | 100 | 1 | 1101 2 | 100 | 1100 | 1101 1 | 200 | 1 | 2 3 | 200 | 1 | 2 1 | 300 | 1 | 1 1 | 400 | 1 | 2 2 | 400 | 1 | 2 1 | 500 | 12 | 24 3 | 500 | 12 | 24 3 | 600 | 12 | 12 4 | 700 | 1 | 1 4 | 800 | 1 | 1 (12 rows) select cn,pn,qty,sum(qty) over (order by cn range between current row and cn following) from sale; --mvd 1->4 cn | pn | qty | sum ----+-----+------+------ 1 | 100 | 1 | 1117 1 | 200 | 1 | 1117 1 | 400 | 1 | 1117 1 | 300 | 1 | 1117 1 | 500 | 12 | 1117 2 | 100 | 1100 | 1128 2 | 400 | 1 | 1128 3 | 600 | 12 | 27 3 | 200 | 1 | 27 3 | 500 | 12 | 27 4 | 700 | 1 | 2 4 | 800 | 1 | 2 (12 rows) select cn,pn,qty,sum(qty) over (order by cn range between cn-1 preceding and cn following) from sale; --mvd 1->4 cn | pn | qty | sum ----+-----+------+------ 1 | 100 | 1 | 1117 1 | 200 | 1 | 1117 1 | 400 | 1 | 1117 1 | 300 | 1 | 1117 1 | 500 | 12 | 1117 2 | 100 | 1100 | 1144 2 | 400 | 1 | 1144 3 | 600 | 12 | 1144 3 | 200 | 1 | 1144 3 | 500 | 12 | 1144 4 | 700 | 1 | 1144 4 | 800 | 1 | 1144 (12 rows) select cn,pn,qty,sum(qty) over (partition by cn order by pn range between cn*100-50 preceding and cn*200 following) as sum from sale; --mvd 1->4 cn | pn | qty | sum ----+-----+------+------ 1 | 100 | 1 | 3 1 | 200 | 1 | 3 1 | 300 | 1 | 14 1 | 400 | 1 | 13 1 | 500 | 12 | 12 3 | 200 | 1 | 25 3 | 500 | 12 | 24 3 | 600 | 12 | 24 2 | 100 | 1100 | 1101 2 | 400 | 1 | 1 4 | 700 | 1 | 2 4 | 800 | 1 | 2 (12 rows) select pn,vn,max(vn) over (order by pn range between cn-1 following and cn-2 following) as max from sale; ERROR: RANGE parameter cannot be negative -- MPP-2036 select cn,qty,sum(qty) over(order by cn range cn preceding) as sum from (select sale.* from sale,customer,vendor where sale.cn=customer.cn and sale.vn=vendor.vn) sale; --mvd 1->3 cn | qty | sum ----+------+------ 1 | 1 | 16 1 | 1 | 16 1 | 1 | 16 1 | 1 | 16 1 | 12 | 16 2 | 1100 | 1117 2 | 1 | 1117 3 | 12 | 1142 3 | 1 | 1142 3 | 12 | 1142 4 | 1 | 1144 4 | 1 | 1144 (12 rows) -- MPP-1744 select cn,vn,ntile(cn) over(partition by cn order by vn) from sale; --mvd 1->3 cn | vn | ntile ----+----+------- 1 | 10 | 1 1 | 20 | 1 1 | 30 | 1 1 | 30 | 1 1 | 50 | 1 3 | 30 | 1 3 | 30 | 2 3 | 40 | 3 2 | 40 | 1 2 | 50 | 2 4 | 40 | 1 4 | 40 | 2 (12 rows) select cn,vn,ntile(qty) over(partition by cn order by vn) from sale; cn | vn | ntile ----+----+------- 1 | 10 | 1 1 | 20 | 1 1 | 30 | 1 1 | 30 | 1 1 | 50 | 1 2 | 40 | 1 2 | 50 | 2 3 | 30 | 1 3 | 30 | 2 3 | 40 | 3 4 | 40 | 1 4 | 40 | 1 (12 rows) select cn,vn,ntile(cn) over(partition by cn+vn order by vn) from sale; cn | vn | ntile ----+----+------- 1 | 10 | 1 1 | 20 | 1 1 | 30 | 1 1 | 30 | 1 1 | 50 | 1 2 | 40 | 1 2 | 50 | 1 3 | 30 | 1 3 | 30 | 2 3 | 40 | 1 4 | 40 | 1 4 | 40 | 2 (12 rows) select cn,vn,ntile(cn+vn) over(partition by cn+vn order by vn) from sale; --mvd 1,2->3 cn | vn | ntile ----+----+------- 1 | 10 | 1 1 | 20 | 1 1 | 30 | 1 1 | 30 | 2 3 | 30 | 1 3 | 30 | 2 3 | 40 | 1 1 | 50 | 1 2 | 40 | 1 4 | 40 | 1 4 | 40 | 2 2 | 50 | 1 (12 rows) -- MPP-2045 SELECT sale.cn,sale.qty, count(cn) OVER(order by sale.cn,sale.qty rows between sale.qty following and 4 following) as count from sale; cn | qty | count ----+------+------- 1 | 1 | 4 1 | 1 | 4 1 | 1 | 4 1 | 1 | 4 1 | 12 | 0 2 | 1 | 4 2 | 1100 | 0 3 | 1 | 4 3 | 12 | 0 3 | 12 | 0 4 | 1 | 1 4 | 1 | 0 (12 rows) -- MPP-2068 SELECT vn,cn,prc, COUNT(floor(sale.cn)) OVER(order by sale.vn asc,sale.cn asc,sale.prc rows prc preceding ) as count FROM sale; vn | cn | prc | count ----+----+------+------- 10 | 1 | 0 | 1 20 | 1 | 0 | 1 30 | 1 | 0 | 1 30 | 1 | 5 | 4 30 | 3 | 5 | 5 30 | 3 | 5 | 6 40 | 2 | 2400 | 7 40 | 3 | 0 | 1 40 | 4 | 1 | 2 40 | 4 | 1 | 2 50 | 1 | 0 | 1 50 | 2 | 0 | 1 (12 rows) -- MPP-2075 SELECT sale.vn,sale.cn, AVG(sale.pn) OVER(order by sale.vn asc range between vn preceding and vn-10 preceding ) as avg from sale; --mvd 1->3 vn | cn | avg ----+----+---------------------- 10 | 1 | 200.0000000000000000 20 | 1 | 200.0000000000000000 30 | 3 | 200.0000000000000000 30 | 1 | 200.0000000000000000 30 | 1 | 200.0000000000000000 30 | 3 | 200.0000000000000000 40 | 4 | 200.0000000000000000 40 | 2 | 200.0000000000000000 40 | 4 | 200.0000000000000000 40 | 3 | 200.0000000000000000 50 | 2 | 200.0000000000000000 50 | 1 | 200.0000000000000000 (12 rows) SELECT sale.qty,sale.cn,sale.vn, AVG(sale.pn) OVER(order by sale.vn asc range between 0 preceding and vn preceding ) as avg from sale; --mvd 3->4 qty | cn | vn | avg ------+----+----+----- 1 | 1 | 10 | 1 | 1 | 20 | 12 | 3 | 30 | 12 | 1 | 30 | 1 | 1 | 30 | 12 | 3 | 30 | 1 | 4 | 40 | 1100 | 2 | 40 | 1 | 4 | 40 | 1 | 3 | 40 | 1 | 2 | 50 | 1 | 1 | 50 | (12 rows) SELECT sale.vn,sale.cn, min(sale.pn) OVER(order by sale.vn asc range between vn preceding and vn-10 preceding ) as min from sale; --mvd 1->3 vn | cn | min ----+----+----- 10 | 1 | 200 20 | 1 | 200 30 | 3 | 200 30 | 1 | 200 30 | 1 | 200 30 | 3 | 200 40 | 4 | 200 40 | 2 | 200 40 | 4 | 200 40 | 3 | 200 50 | 2 | 200 50 | 1 | 200 (12 rows) SELECT sale.qty,sale.cn,sale.vn, min(sale.pn) OVER(order by sale.vn asc range between 0 preceding and vn preceding ) as min from sale; --mvd 3->4 qty | cn | vn | min ------+----+----+----- 1 | 1 | 10 | 1 | 1 | 20 | 12 | 3 | 30 | 12 | 1 | 30 | 1 | 1 | 30 | 12 | 3 | 30 | 1 | 4 | 40 | 1100 | 2 | 40 | 1 | 4 | 40 | 1 | 3 | 40 | 1 | 2 | 50 | 1 | 1 | 50 | (12 rows) -- MPP-2078 SELECT sale.cn,sale.vn, COUNT(floor(sale.cn)) OVER(partition by sale.cn order by sale.vn asc range between 1 preceding and floor(sale.cn) preceding ) FROM sale; --mvd 1,2->3 cn | vn | count ----+----+------- 1 | 10 | 0 1 | 20 | 0 1 | 30 | 0 1 | 30 | 0 1 | 50 | 0 3 | 30 | 0 3 | 30 | 0 3 | 40 | 0 2 | 40 | 0 2 | 50 | 0 4 | 40 | 0 4 | 40 | 0 (12 rows) -- MPP-2080 SELECT sale.vn,qty, COUNT(qty) OVER(order by sale.vn desc range between unbounded preceding and 1 preceding) FROM sale; --mvd 1->3 vn | qty | count ----+------+------- 50 | 1 | 0 50 | 1 | 0 40 | 1 | 2 40 | 1100 | 2 40 | 1 | 2 40 | 1 | 2 30 | 12 | 6 30 | 12 | 6 30 | 1 | 6 30 | 12 | 6 20 | 1 | 10 10 | 1 | 11 (12 rows) -- MPP-2081 SELECT cn,qty,floor(prc/cn), COUNT(floor(sale.pn*sale.prc)) OVER(order by sale.cn asc range between floor(sale.qty) preceding and floor(sale.prc/sale.cn) preceding) from sale; --mvd 1->4 cn | qty | floor | count ----+------+-------+------- 1 | 1 | 0 | 5 1 | 1 | 0 | 5 1 | 1 | 0 | 5 1 | 1 | 0 | 5 1 | 12 | 5 | 0 2 | 1100 | 1200 | 0 2 | 1 | 0 | 7 3 | 12 | 1 | 7 3 | 1 | 0 | 5 3 | 12 | 1 | 7 4 | 1 | 0 | 5 4 | 1 | 0 | 5 (12 rows) -- MPP-2135 select cn,sum(qty) over(order by cn), sum(qty) from sale group by cn,qty; --mvd 1->2 cn | sum | sum ----+------+------ 1 | 13 | 12 1 | 13 | 4 2 | 1114 | 1100 2 | 1114 | 1 3 | 1127 | 24 3 | 1127 | 1 4 | 1128 | 2 (7 rows) select cn,sum(sum(qty)) over(order by cn), sum(qty) from sale group by cn,qty; --mvd 1->2 cn | sum | sum ----+------+------ 1 | 16 | 12 1 | 16 | 4 2 | 1117 | 1100 2 | 1117 | 1 3 | 1142 | 24 3 | 1142 | 1 4 | 1144 | 2 (7 rows) select cn,sum(sum(qty) + 1) over(order by cn), sum(qty) + 1 from sale group by cn,qty; --mvd 1->2 cn | sum | ?column? ----+------+---------- 1 | 18 | 13 1 | 18 | 5 2 | 1121 | 1101 2 | 1121 | 2 3 | 1148 | 25 3 | 1148 | 2 4 | 1151 | 3 (7 rows) select cn,sum(qty+1) over(order by cn), sum(qty+1) from sale group by cn,qty; --mvd 1->2 cn | sum | sum ----+------+------ 1 | 15 | 13 1 | 15 | 8 2 | 1118 | 1101 2 | 1118 | 2 3 | 1133 | 26 3 | 1133 | 2 4 | 1135 | 4 (7 rows) -- MPP-2152 SELECT cn, pn, dt, PERCENT_RANK() OVER(partition by cn,dt order by cn desc), LEAD(pn,cn,NULL) OVER(partition by cn,dt order by pn, cn desc) FROM sale; --mvd 1,3->4 cn | pn | dt | percent_rank | lead ----+-----+------------+--------------+------ 1 | 100 | 05-01-1401 | 0 | 2 | 400 | 06-01-1401 | 0 | 3 | 200 | 04-01-1401 | 0 | 4 | 700 | 06-01-1401 | 0 | 4 | 800 | 06-01-1401 | 0 | 1 | 200 | 03-01-1401 | 0 | 1 | 300 | 05-02-1401 | 0 | 1 | 400 | 06-01-1401 | 0 | 500 1 | 500 | 06-01-1401 | 0 | 2 | 100 | 01-01-1401 | 0 | 3 | 500 | 06-01-1401 | 0 | 3 | 600 | 06-01-1401 | 0 | (12 rows) -- MPP-2163 SELECT cn, pn, vn, dt, qty, ROW_NUMBER() OVER( partition by vn, qty, dt order by cn asc ), PERCENT_RANK() OVER( partition by vn, dt order by cn desc ), PERCENT_RANK() OVER( order by pn asc ) FROM (SELECT * FROM sale) sale; --mvd 3,4,5->6; 3,4->7 cn | pn | vn | dt | qty | row_number | percent_rank | percent_rank ----+-----+----+------------+------+------------+--------------+------------------- 2 | 100 | 40 | 01-01-1401 | 1100 | 1 | 0 | 0 1 | 100 | 20 | 05-01-1401 | 1 | 1 | 0 | 0 3 | 200 | 40 | 04-01-1401 | 1 | 1 | 0 | 0.181818181818182 1 | 200 | 10 | 03-01-1401 | 1 | 1 | 0 | 0.181818181818182 1 | 300 | 30 | 05-02-1401 | 1 | 1 | 0 | 0.363636363636364 2 | 400 | 50 | 06-01-1401 | 1 | 2 | 0 | 0.454545454545455 1 | 400 | 50 | 06-01-1401 | 1 | 1 | 1 | 0.454545454545455 1 | 500 | 30 | 06-01-1401 | 12 | 1 | 1 | 0.636363636363636 3 | 500 | 30 | 06-01-1401 | 12 | 3 | 0 | 0.636363636363636 3 | 600 | 30 | 06-01-1401 | 12 | 2 | 0 | 0.818181818181818 4 | 700 | 40 | 06-01-1401 | 1 | 2 | 0 | 0.909090909090909 4 | 800 | 40 | 06-01-1401 | 1 | 1 | 0 | 1 (12 rows) -- MPP-2189 create view v1 as select dt, sum(cn) over(order by grouping(cn) range grouping(cn) preceding) from sale group by rollup(cn,dt); \d+ v1 View "olap_window_seq.v1" Column | Type | Modifiers | Storage | Description --------+--------+-----------+---------+------------- dt | date | | plain | sum | bigint | | plain | View definition: SELECT "Window".dt, sum("Window".cn) OVER (ORDER BY "Window".att_3 RANGE "Window".att_3 PRECEDING) AS sum FROM ( SELECT sale.cn, sale.dt, grouping(sale.cn) AS att_3 FROM sale GROUP BY ROLLUP (sale.cn, sale.dt)) "Window"(cn, dt, att_3); drop view v1; -- MPP-2194, MPP-2236 drop table if exists win_test_for_window_seq; create table win_test_for_window_seq (i int, j int); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into win_test_for_window_seq values (0,0), (1,null), (2, null), (3,null); select i,j,sum(i) over(order by j range 1 preceding) from win_test_for_window_seq; --mvd 2->3 i | j | sum ---+---+----- 0 | 0 | 0 2 | | 6 3 | | 6 1 | | 6 (4 rows) select i,j,sum(j) over(order by i rows 1 preceding) from win_test_for_window_seq; i | j | sum ---+---+----- 0 | 0 | 0 1 | | 0 2 | | 3 | | (4 rows) -- MPP-2305 SELECT sale.vn,sale.cn,sale.pn, CUME_DIST() OVER(partition by sale.vn,sale.cn order by sale.pn desc) as cume_dist1, CUME_DIST() OVER(partition by sale.cn,sale.vn order by sale.cn asc) as cume_dist2 FROM sale order by 1,2,3; --order 1,2,3 vn | cn | pn | cume_dist1 | cume_dist2 ----+----+-----+------------+------------ 10 | 1 | 200 | 1 | 1 20 | 1 | 100 | 1 | 1 30 | 1 | 300 | 1 | 1 30 | 1 | 500 | 0.5 | 1 30 | 3 | 500 | 1 | 1 30 | 3 | 600 | 0.5 | 1 40 | 2 | 100 | 1 | 1 40 | 3 | 200 | 1 | 1 40 | 4 | 700 | 1 | 1 40 | 4 | 800 | 0.5 | 1 50 | 1 | 400 | 1 | 1 50 | 2 | 400 | 1 | 1 (12 rows) -- MPP-2322 select ord, pn,cn,vn,sum(vn) over (order by ord, pn rows between cn following and cn+1 following) as sum from sale_ord; ord | pn | cn | vn | sum -----+-----+----+----+----- 1 | 100 | 2 | 40 | 60 2 | 200 | 1 | 10 | 60 3 | 200 | 3 | 40 | 100 4 | 100 | 1 | 20 | 80 5 | 300 | 1 | 30 | 100 6 | 400 | 1 | 50 | 80 7 | 400 | 2 | 50 | 60 8 | 500 | 1 | 30 | 60 9 | 500 | 3 | 30 | 40 10 | 600 | 3 | 30 | 11 | 700 | 4 | 40 | 12 | 800 | 4 | 40 | (12 rows) select ord, pn,cn,vn,sum(vn) over (order by ord, pn rows between cn following and cn following) as sum from sale_ord; ord | pn | cn | vn | sum -----+-----+----+----+----- 1 | 100 | 2 | 40 | 40 2 | 200 | 1 | 10 | 40 3 | 200 | 3 | 40 | 50 4 | 100 | 1 | 20 | 30 5 | 300 | 1 | 30 | 50 6 | 400 | 1 | 50 | 50 7 | 400 | 2 | 50 | 30 8 | 500 | 1 | 30 | 30 9 | 500 | 3 | 30 | 40 10 | 600 | 3 | 30 | 11 | 700 | 4 | 40 | 12 | 800 | 4 | 40 | (12 rows) -- MPP-2323 select ord, cn,vn,sum(vn) over (order by ord rows between 3 following and floor(cn) following ) from sale_ord; ord | cn | vn | sum -----+----+----+----- 1 | 2 | 40 | 2 | 1 | 10 | 3 | 3 | 40 | 50 4 | 1 | 20 | 5 | 1 | 30 | 6 | 1 | 50 | 7 | 2 | 50 | 8 | 1 | 30 | 9 | 3 | 30 | 40 10 | 3 | 30 | 11 | 4 | 40 | 12 | 4 | 40 | (12 rows) -- domain suport create domain wintestd as int default count(*) over (); ERROR: window functions are not allowed in DEFAULT expressions create domain wintestd as int check (value < count(*) over ()); ERROR: window functions are not allowed in check constraints -- MPP-3295 -- begin equivalent select cn,vn,rank() over (partition by cn order by vn) as rank from sale group by cn,vn order by rank; --mvd 1->3 cn | vn | rank ----+----+------ 3 | 30 | 1 1 | 10 | 1 2 | 40 | 1 4 | 40 | 1 2 | 50 | 2 1 | 20 | 2 3 | 40 | 2 1 | 30 | 3 1 | 50 | 4 (9 rows) select cn,vn,rank() over (partition by cn order by vn) as rank from (select cn,vn from sale group by cn,vn) sale order by rank; --mvd 1->3 cn | vn | rank ----+----+------ 3 | 30 | 1 1 | 10 | 1 2 | 40 | 1 4 | 40 | 1 2 | 50 | 2 1 | 20 | 2 3 | 40 | 2 1 | 30 | 3 1 | 50 | 4 (9 rows) -- end equivalent -- begin equivalent select cn,vn, 1+rank() over (partition by cn order by vn) as rank from sale group by cn,vn order by rank; --mvd 1->3 cn | vn | rank ----+----+------ 3 | 30 | 2 1 | 10 | 2 2 | 40 | 2 4 | 40 | 2 2 | 50 | 3 1 | 20 | 3 3 | 40 | 3 1 | 30 | 4 1 | 50 | 5 (9 rows) select cn,vn, 1+rank() over(partition by cn order by vn) as rank from (select cn,vn from sale group by cn,vn) sale order by rank; --mvd 1->3 cn | vn | rank ----+----+------ 3 | 30 | 2 1 | 10 | 2 2 | 40 | 2 4 | 40 | 2 2 | 50 | 3 1 | 20 | 3 3 | 40 | 3 1 | 30 | 4 1 | 50 | 5 (9 rows) -- end equivalent -- begin equivalent select cn,vn, sum(qty), 1+rank() over (partition by cn order by vn) as rank from sale group by cn,vn order by rank; --mvd 1->3 cn | vn | sum | rank ----+----+------+------ 3 | 30 | 24 | 2 1 | 10 | 1 | 2 2 | 40 | 1100 | 2 4 | 40 | 2 | 2 2 | 50 | 1 | 3 1 | 20 | 1 | 3 3 | 40 | 1 | 3 1 | 30 | 13 | 4 1 | 50 | 1 | 5 (9 rows) select cn,vn, sum, 1+rank() over (partition by cn order by vn) as rank from (select cn,vn,sum(qty) as sum from sale group by cn, vn) sale order by rank; --mvd 1->3 cn | vn | sum | rank ----+----+------+------ 3 | 30 | 24 | 2 1 | 10 | 1 | 2 2 | 40 | 1100 | 2 4 | 40 | 2 | 2 2 | 50 | 1 | 3 1 | 20 | 1 | 3 3 | 40 | 1 | 3 1 | 30 | 13 | 4 1 | 50 | 1 | 5 (9 rows) -- end equivalent select cn, first_value(NULL::text) over (partition by cn order by case when 1=1 then pn || ' ' else 'test' end) from sale order by first_value(NULL::text) over ( partition by cn order by case when 1=1 then (pn || ' ') else 'test'::character varying(15) end); --mvd 1->2 cn | first_value ----+------------- 1 | 1 | 1 | 1 | 3 | 3 | 3 | 1 | 2 | 4 | 4 | 2 | (12 rows) select cn, first_value(NULL::text) over (partition by cn order by case when 1=1 then pn || ' ' else 'test' end) from sale order by first_value(NULL::text) over ( partition by cn order by case when 1=1 then (pn || ' ') else 'test' end); --mvd 1->2 cn | first_value ----+------------- 1 | 1 | 1 | 1 | 3 | 3 | 3 | 1 | 2 | 4 | 4 | 2 | (12 rows) -- MPP-4836 select pcolor, pname, pn, row_number() over (w) as n, lag(pn+0) over (w) as l0, lag(pn+1) over (w) as l1, lag(pn+2) over (w) as l2, lag(pn+3) over (w) as l3, lag(pn+4) over (w) as l4, lag(pn+5) over (w) as l5, lag(pn+6) over (w) as l6, lag(pn+7) over (w) as l7, lag(pn+8) over (w) as l8, lag(pn+9) over (w) as l9, lag(pn+10) over (w) as l10, lag(pn+11) over (w) as l11, lag(pn+12) over (w) as l12, lag(pn+13) over (w) as l13, lag(pn+14) over (w) as l14, lag(pn+15) over (w) as l15, lag(pn+16) over (w) as l16, lag(pn+17) over (w) as l17, lag(pn+18) over (w) as l18, lag(pn+19) over (w) as l19, lag(pn+20) over (w) as l20, lag(pn+21) over (w) as l21, lag(pn+22) over (w) as l22, lag(pn+23) over (w) as l23, lag(pn+24) over (w) as l24, lag(pn+25) over (w) as l25, lag(pn+26) over (w) as l26, lag(pn+27) over (w) as l27, lag(pn+28) over (w) as l28, lag(pn+29) over (w) as l29, lag(pn+30) over (w) as l30, lag(pn+31) over (w) as l31, lag(pn+32) over (w) as l32 from product window w as (partition by pcolor order by pname) order by 1,2,3; pcolor | pname | pn | n | l0 | l1 | l2 | l3 | l4 | l5 | l6 | l7 | l8 | l9 | l10 | l11 | l12 | l13 | l14 | l15 | l16 | l17 | l18 | l19 | l20 | l21 | l22 | l23 | l24 | l25 | l26 | l27 | l28 | l29 | l30 | l31 | l32 -----------+-----------+-----+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+----- Black | Dream | 200 | 1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Black | Sword | 100 | 2 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 Chocolate | Donuts | 600 | 1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Clear | Justice | 400 | 1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Grey | Castle | 300 | 1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Grey | Fries | 800 | 2 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 Grey | Hamburger | 700 | 3 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 Plain | Donuts | 500 | 1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (8 rows) -- Once upon a time, there was a bug in deparsing a WindowAgg node with EXPLAIN -- that this query triggered (MPP-4840) explain select n from ( select row_number() over () from (values (0)) as t(x) ) as r(n) group by n; QUERY PLAN ------------------------------------------------------------------------- HashAggregate (cost=0.02..0.03 rows=1 width=8) Group By: pg_catalog.row_number() -> WindowAgg (cost=0.00..0.01 rows=1 width=0) -> Values Scan on "*VALUES*" (cost=0.00..0.01 rows=1 width=0) Settings: optimizer=off Optimizer status: Postgres query optimizer (6 rows) -- Test for MPP-11645 create table olap_window_r (a int, b int, x int, y int, z int ) distributed by (b); insert into olap_window_r values ( 1, 17, 419, 291, 2513 ), ( 2, 16, 434, 293, 2513 ), ( 3, 15, 439, 295, 2483 ), ( 4, 14, 445, 297, 2675 ), ( 5, 13, 473, 299, 2730 ), ( 6, 12, 475, 303, 2765 ), ( 7, 11, 479, 305, 2703 ), ( 8, 10, 502, 307, 2749 ), ( 9, 9, 528, 308, 2850 ), ( 10, 8, 532, 309, 2900 ), ( 11, 7, 567, 315, 2970 ), ( 12, 6, 570, 317, 3025 ), ( 13, 5, 635, 319, 3045 ), ( 14, 4, 653, 320, 3093 ), ( 15, 3, 711, 321, 3217 ), ( 16, 2, 770, 325, 3307 ), ( 17, 1, 778, 329, 3490 ); select b, sum(x) over (partition by b), 10*b from olap_window_r order by b; --order 3 b | sum | ?column? ----+-----+---------- 1 | 778 | 10 2 | 770 | 20 3 | 711 | 30 4 | 653 | 40 5 | 635 | 50 6 | 570 | 60 7 | 567 | 70 8 | 532 | 80 9 | 528 | 90 10 | 502 | 100 11 | 479 | 110 12 | 475 | 120 13 | 473 | 130 14 | 445 | 140 15 | 439 | 150 16 | 434 | 160 17 | 419 | 170 (17 rows) select sum(x) over (partition by b), 10*b from olap_window_r order by b; --order 2 sum | ?column? -----+---------- 778 | 10 770 | 20 711 | 30 653 | 40 635 | 50 570 | 60 567 | 70 532 | 80 528 | 90 502 | 100 479 | 110 475 | 120 473 | 130 445 | 140 439 | 150 434 | 160 419 | 170 (17 rows) select a, sum(x) over (partition by a), 10*a from olap_window_r order by a; --order 3 a | sum | ?column? ----+-----+---------- 1 | 419 | 10 2 | 434 | 20 3 | 439 | 30 4 | 445 | 40 5 | 473 | 50 6 | 475 | 60 7 | 479 | 70 8 | 502 | 80 9 | 528 | 90 10 | 532 | 100 11 | 567 | 110 12 | 570 | 120 13 | 635 | 130 14 | 653 | 140 15 | 711 | 150 16 | 770 | 160 17 | 778 | 170 (17 rows) select sum(x) over (partition by a), 10*a from olap_window_r order by a; -- order 2 sum | ?column? -----+---------- 419 | 10 434 | 20 439 | 30 445 | 40 473 | 50 475 | 60 479 | 70 502 | 80 528 | 90 532 | 100 567 | 110 570 | 120 635 | 130 653 | 140 711 | 150 770 | 160 778 | 170 (17 rows) drop table if exists olap_window_r cascade; --ignore -- End MPP-11645 -- MPP-12082 select f, sum(g) over (partition by f) from (select 'A', 1) b(j, g) join (select 'A', 'B') c(j, f) using(j) group by 1, b.g; f | sum ---+----- B | 1 (1 row) select f, sum(b.g) over (partition by f) from (select 'A', 1) b(j, g) join (select 'A', 'B') c(j, f) using(j) group by 1, g; f | sum ---+----- B | 1 (1 row) select 2*b.g, lower(c.f), sum(2*b.g) over (partition by lower(c.f)) from (select 'A', 1) b(j, g) join (select 'A', 'B') c(j, f) using(j) group by 2*b.g, lower(c.f); ?column? | lower | sum ----------+-------+----- 2 | b | 2 (1 row) select 2*g, lower(c.f), sum(2*g) over (partition by lower(c.f)) from (select 'A', 1) b(j, g) join (select 'A', 'B') c(j, f) using(j) group by 2*b.g, lower(f); ERROR: unresolved grouping key in window query HINT: You might need to use explicit aliases and/or to refer to grouping keys in the same way throughout the query. -- End MPP-12082 -- MPP-12913 select count(*) over (partition by 1 order by cn rows between 1 preceding and 1 preceding) from sale; count ------- 0 1 1 1 1 1 1 1 1 1 1 1 (12 rows) -- End MPP-12913 -- MPP-13710 create table redundant_sort_check (i int, j int, k int) distributed by (i); explain select count(*) over (order by i), count(*) over (partition by i order by j) from redundant_sort_check; QUERY PLAN -------------------------------------------------------------------------------------------------- WindowAgg (cost=7208.12..9934.62 rows=77900 width=8) Order By: i -> Gather Motion 3:1 (slice1; segments: 3) (cost=7208.12..8766.12 rows=77900 width=8) Merge Key: i, j -> WindowAgg (cost=7208.12..8766.12 rows=25967 width=8) Partition By: i Order By: j -> Sort (cost=7208.12..7402.87 rows=25967 width=8) Sort Key: i, j -> Seq Scan on redundant_sort_check (cost=0.00..879.00 rows=25967 width=8) Optimizer: Postgres query optimizer (11 rows) -- End of MPP-13710 -- MPP-13879 create table num_range as select a::numeric from generate_series(1, 10)a; NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'a' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. select a, max(a) over (order by a range between current row and 2 following) from num_range; a | max ----+----- 1 | 3 2 | 4 3 | 5 4 | 6 5 | 7 6 | 8 7 | 9 8 | 10 9 | 10 10 | 10 (10 rows) -- End of MPP-13879 -- MPP-13969 create table esc176_1(id int, seq int, val float, clickdate timestamp); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into esc176_1 values(1, 1, 0.2, '2011-08-18 04:59:35.471494'), (1, 2, 0.1, '2011-08-18 04:59:45.920501'), (1, 3, 0.5, '2011-08-18 04:59:51.174672'), (1, 4, 0.7, '2011-08-18 04:59:57.343782'); select id, seq, clickdate, sum(val) over (partition by id order by clickdate range between interval '0 seconds' following and '1000 seconds' following) from esc176_1; id | seq | clickdate | sum ----+-----+---------------------------------+----- 1 | 1 | Thu Aug 18 04:59:35.471494 2011 | 1.5 1 | 2 | Thu Aug 18 04:59:45.920501 2011 | 1.3 1 | 3 | Thu Aug 18 04:59:51.174672 2011 | 1.2 1 | 4 | Thu Aug 18 04:59:57.343782 2011 | 0.7 (4 rows) -- End of MPP-13969 drop table if exists olap_window_seq_test; NOTICE: table "olap_window_seq_test" does not exist, skipping create table olap_window_seq_test (n numeric, d date); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'n' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into olap_window_seq_test values (12, '2011-05-01'), (34, '2011-05-02'), (89, '2011-05-03'); select stddev(n) over(order by d range interval '1 day' preceding), n from olap_window_seq_test; stddev | n ---------------------+---- | 12 15.5563491861040455 | 34 38.8908729652601138 | 89 (3 rows) select stddev(n) over(order by d range interval '1 day' preceding), sum(n) over(order by d range interval '1 day' preceding), avg(n) over(order by d range interval '1 day' preceding), n from olap_window_seq_test; stddev | sum | avg | n ---------------------+-----+---------------------+---- | 12 | 12.0000000000000000 | 12 15.5563491861040455 | 46 | 23.0000000000000000 | 34 38.8908729652601138 | 123 | 61.5000000000000000 | 89 (3 rows) select stddev(n) over(order by d range interval '2 day' preceding), sum(n) over(order by d range interval '2 day' preceding), avg(n) over(order by d range interval '2 day' preceding), n from olap_window_seq_test; stddev | sum | avg | n ---------------------+-----+---------------------+---- | 12 | 12.0000000000000000 | 12 15.5563491861040455 | 46 | 23.0000000000000000 | 34 39.6610640301038822 | 135 | 45.0000000000000000 | 89 (3 rows) select stddev(n) over(order by d range between current row and interval '1 day' following), sum(n) over(order by d range between current row and interval '1 day' following), avg(n) over(order by d range between current row and interval '1 day' following), n from olap_window_seq_test; stddev | sum | avg | n ---------------------+-----+---------------------+---- 15.5563491861040455 | 46 | 23.0000000000000000 | 12 38.8908729652601138 | 123 | 61.5000000000000000 | 34 | 89 | 89.0000000000000000 | 89 (3 rows) -- This test examines the case that a statement invokes multiple lead functions, -- which are not sorted regarding the rows that they use and projected attributes are varlen. DROP TABLE IF EXISTS empsalary; NOTICE: table "empsalary" does not exist, skipping CREATE TABLE empsalary( depname varchar, empno bigint, salary char(8), enroll_date date ); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'depname' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO empsalary VALUES('develop', 8, '6000', '2006/10/01'); INSERT INTO empsalary VALUES('develop', 11, '5200', '2007/08/15'); INSERT INTO empsalary VALUES('develop', 9, '4500', '2008/01/01'); -- First lead retrieves data from one tuple ahead, second lead function retrieves data from two tuples ahead, while third one -- gets data from one tuple ahead again. select * , lead(salary,1) over (partition by depname order by salary desc) qianzhi1, lead(salary,2) over (partition by depname order by salary desc) qianzhi2, lead(empno,1) over (partition by depname order by salary desc) qianzhi11 from empsalary; depname | empno | salary | enroll_date | qianzhi1 | qianzhi2 | qianzhi11 ---------+-------+----------+-------------+----------+----------+----------- develop | 8 | 6000 | 10-01-2006 | 5200 | 4500 | 11 develop | 11 | 5200 | 08-15-2007 | 4500 | | 9 develop | 9 | 4500 | 01-01-2008 | | | (3 rows) -- Lead functions are in order. select * , lead(salary,1) over (partition by depname order by salary desc) qianzhi1, lead(empno,1) over (partition by depname order by salary desc) qianzhi11, lead(salary,2) over (partition by depname order by salary desc) qianzhi2 from empsalary; depname | empno | salary | enroll_date | qianzhi1 | qianzhi11 | qianzhi2 ---------+-------+----------+-------------+----------+-----------+---------- develop | 8 | 6000 | 10-01-2006 | 5200 | 11 | 4500 develop | 11 | 5200 | 08-15-2007 | 4500 | 9 | develop | 9 | 4500 | 01-01-2008 | | | (3 rows) DROP TABLE IF EXISTS empsalary; CREATE TABLE empsalary( depname varchar, empno bigint, salary numeric(22, 6), enroll_date date ); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'depname' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO empsalary VALUES('develop', 8, 6000, '2006/10/01'); INSERT INTO empsalary VALUES('develop', 11, 5200, '2007/08/15'); INSERT INTO empsalary VALUES('develop', 9, 4500, '2008/01/01'); -- Similar to the first statement using numeric. select * , lead(salary,1) over (partition by depname order by salary desc) qianzhi1, lead(salary,2) over (partition by depname order by salary desc) qianzhi2, lead(empno,1) over (partition by depname order by salary desc) qianzhi11 from empsalary; depname | empno | salary | enroll_date | qianzhi1 | qianzhi2 | qianzhi11 ---------+-------+-------------+-------------+-------------+-------------+----------- develop | 8 | 6000.000000 | 10-01-2006 | 5200.000000 | 4500.000000 | 11 develop | 11 | 5200.000000 | 08-15-2007 | 4500.000000 | | 9 develop | 9 | 4500.000000 | 01-01-2008 | | | (3 rows) DROP TABLE IF EXISTS empsalary; CREATE TABLE empsalary( depname varchar, empno bigint, salary int, enroll_date date ); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'depname' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO empsalary VALUES('develop', 8, 6000, '2006/10/01'); INSERT INTO empsalary VALUES('develop', 11, 5200, '2007/08/15'); INSERT INTO empsalary VALUES('develop', 9, 4500, '2008/01/01'); -- Similar to the first statement using int. select * , lead(salary,1) over (partition by depname order by salary desc) qianzhi1, lead(salary,2) over (partition by depname order by salary desc) qianzhi2, lead(empno,1) over (partition by depname order by salary desc) qianzhi11 from empsalary; depname | empno | salary | enroll_date | qianzhi1 | qianzhi2 | qianzhi11 ---------+-------+--------+-------------+----------+----------+----------- develop | 8 | 6000 | 10-01-2006 | 5200 | 4500 | 11 develop | 11 | 5200 | 08-15-2007 | 4500 | | 9 develop | 9 | 4500 | 01-01-2008 | | | (3 rows) create table foo (a int4) distributed by (a); create table bar (a int4, b int4) distributed by (a, b); insert into foo select g from generate_series(1, 10) g; insert into bar select g%2, g from generate_series(1, 5) g; select foo.a, sum(b) over (partition by bar.a order by bar.b) from foo, bar where foo.a = bar.a; a | sum ---+----- 1 | 1 1 | 4 1 | 9 (3 rows) explain select foo.a, sum(b) over (partition by bar.a order by bar.b) from foo, bar where foo.a = bar.a; QUERY PLAN ---------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice2; segments: 3) (cost=3.46..3.50 rows=5 width=12) -> WindowAgg (cost=3.46..3.50 rows=3 width=12) Partition By: bar.a Order By: bar.b -> Sort (cost=3.46..3.47 rows=3 width=12) Sort Key: bar.a, bar.b -> Hash Join (cost=1.21..3.40 rows=3 width=12) Hash Cond: foo.a = bar.a -> Seq Scan on foo (cost=0.00..2.10 rows=5 width=4) -> Hash (cost=1.15..1.15 rows=3 width=8) -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.15 rows=3 width=8) Hash Key: bar.a -> Seq Scan on bar (cost=0.00..1.05 rows=3 width=8) (14 rows) drop table foo, bar; -- Test to verify fix for https://github.com/greenplum-db/gpdb/issues/2571 drop table if exists foo; drop table if exists bar; create table foo (a int, b int) distributed by (a); create table bar (c int, d int) distributed by (c); insert into foo select i,i from generate_series(1,10) i; insert into bar select i,i from generate_series(1,10) i; set optimizer_segments to 1; SELECT bar.*, count(*) OVER() AS e FROM foo, bar where foo.b = bar.d; c | d | e ----+----+---- 1 | 1 | 10 2 | 2 | 10 3 | 3 | 10 4 | 4 | 10 5 | 5 | 10 6 | 6 | 10 7 | 7 | 10 8 | 8 | 10 9 | 9 | 10 10 | 10 | 10 (10 rows) reset optimizer_segments; drop table foo, bar; CREATE TABLE foo (a int, b int, c int, d int); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into foo select i,i,i,i from generate_series(1, 10) i; EXPLAIN SELECT count(*) over (PARTITION BY a ORDER BY b, c, d) as count1, count(*) over (PARTITION BY a ORDER BY b, c) as count2, count(*) over (PARTITION BY a ORDER BY b) as count3, count(*) over (PARTITION BY a ORDER BY c) as count1, count(*) over (PARTITION BY a ORDER BY c, b) as count2, count(*) over (PARTITION BY a ORDER BY c, b, d) as count3 FROM foo; QUERY PLAN ---------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=4.06..4.68 rows=10 width=16) -> WindowAgg (cost=4.06..4.68 rows=4 width=16) Partition By: a Order By: b -> WindowAgg (cost=4.06..4.51 rows=4 width=16) Partition By: a Order By: b, c -> WindowAgg (cost=4.06..4.31 rows=4 width=16) Partition By: a Order By: b, c, d -> Sort (cost=4.06..4.08 rows=4 width=16) Sort Key: a, b, c, d -> WindowAgg (cost=3.27..3.89 rows=4 width=16) Partition By: a Order By: c -> WindowAgg (cost=3.27..3.72 rows=4 width=16) Partition By: a Order By: c, b -> WindowAgg (cost=3.27..3.52 rows=4 width=16) Partition By: a Order By: c, b, d -> Sort (cost=3.27..3.29 rows=4 width=16) Sort Key: a, c, b, d -> Seq Scan on foo (cost=0.00..3.10 rows=4 width=16) Optimizer: Postgres query optimizer (25 rows) drop table foo; -- test predicate push down in subqueries for quals containing windowref nodes -- start_ignore drop table if exists window_preds; NOTICE: table "window_preds" does not exist, skipping create table window_preds(i int, j int, k int); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into window_preds values(1,2,3); insert into window_preds values(2,3,4); insert into window_preds values(3,4,5); insert into window_preds values(4,5,6); insert into window_preds values(5,6,7); insert into window_preds values(6,7,8); -- end_ignore -- for planner qual k = 1 should not be pushed down in the subquery as it has window refs at top level of subquery. orca is able to push down the predicate to appropriate node explain select k from ( select row_number() over()+2 as k from window_preds union all select row_number() over()+2 as k from window_preds) as t where k = 3; QUERY PLAN --------------------------------------------------------------------------------------------------- Subquery Scan on t (cost=0.00..2.09 rows=1 width=8) Filter: t.k = 3 -> Append (cost=0.00..2.07 rows=2 width=8) -> WindowAgg (cost=0.00..1.02 rows=1 width=0) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.01 rows=1 width=0) -> Seq Scan on window_preds (cost=0.00..1.01 rows=1 width=0) -> WindowAgg (cost=0.00..1.02 rows=1 width=0) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.01 rows=1 width=0) -> Seq Scan on window_preds window_preds_1 (cost=0.00..1.01 rows=1 width=0) Optimizer: Postgres query optimizer (10 rows) select k from ( select row_number() over()+2 as k from window_preds union all select row_number() over()+2 as k from window_preds) as t where k = 3; k --- 3 3 (2 rows) explain insert into window_preds select k from ( select row_number() over()+2 as k from window_preds union all select row_number() over()+2 as k from window_preds) as t where k = 3; QUERY PLAN --------------------------------------------------------------------------------------------------------------- Insert on window_preds (cost=0.00..2.10 rows=1 width=8) -> Redistribute Motion 1:3 (slice3; segments: 1) (cost=0.00..2.10 rows=1 width=8) Hash Key: (t.k::integer) -> Subquery Scan on t (cost=0.00..2.10 rows=1 width=8) Filter: t.k = 3 -> Append (cost=0.00..2.07 rows=2 width=8) -> WindowAgg (cost=0.00..1.02 rows=1 width=0) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.01 rows=1 width=0) -> Seq Scan on window_preds window_preds_1 (cost=0.00..1.01 rows=1 width=0) -> WindowAgg (cost=0.00..1.02 rows=1 width=0) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.01 rows=1 width=0) -> Seq Scan on window_preds window_preds_2 (cost=0.00..1.01 rows=1 width=0) Optimizer: Postgres query optimizer (13 rows) insert into window_preds select k from ( select row_number() over()+2 as k from window_preds union all select row_number() over()+2 as k from window_preds) as t where k = 3; explain SELECT t.k FROM window_preds p1, window_preds p2, (SELECT ROW_NUMBER() OVER() AS k FROM window_preds union all SELECT ROW_NUMBER() OVER() AS k FROM window_preds) AS t WHERE t.k = 1 limit 1; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- Limit (cost=20000000000.00..20000000001.30 rows=1 width=8) -> Nested Loop (cost=20000000000.00..20000000004.31 rows=4 width=8) -> Gather Motion 3:1 (slice2; segments: 3) (cost=10000000000.00..10000000002.17 rows=4 width=0) -> Nested Loop (cost=10000000000.00..10000000002.10 rows=2 width=0) -> Seq Scan on window_preds p1 (cost=0.00..1.01 rows=1 width=0) -> Materialize (cost=0.00..1.06 rows=1 width=0) -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..1.05 rows=1 width=0) -> Seq Scan on window_preds p2 (cost=0.00..1.01 rows=1 width=0) -> Materialize (cost=0.00..2.09 rows=1 width=8) -> Subquery Scan on t (cost=0.00..2.09 rows=1 width=8) Filter: t.k = 1 -> Append (cost=0.00..2.06 rows=2 width=8) -> WindowAgg (cost=0.00..1.02 rows=1 width=0) -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..1.01 rows=1 width=0) -> Seq Scan on window_preds (cost=0.00..1.01 rows=1 width=0) -> WindowAgg (cost=0.00..1.02 rows=1 width=0) -> Gather Motion 3:1 (slice4; segments: 3) (cost=0.00..1.01 rows=1 width=0) -> Seq Scan on window_preds window_preds_1 (cost=0.00..1.01 rows=1 width=0) Optimizer: Postgres query optimizer (19 rows) SELECT t.k FROM window_preds p1, window_preds p2, (SELECT ROW_NUMBER() OVER() AS k FROM window_preds union all SELECT ROW_NUMBER() OVER() AS k FROM window_preds) AS t WHERE t.k = 1 limit 1; k --- 1 (1 row) explain with CTE as (select i, row_number() over (partition by j) j from window_preds union all select i, row_number() over (partition by j) from window_preds) select * from cte where j = 1; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..0.04 rows=1 width=12) -> Subquery Scan on cte (cost=0.00..0.04 rows=1 width=12) Filter: cte.j = 1 -> Append (cost=1.04..2.14 rows=1 width=12) -> Subquery Scan on "*SELECT* 1" (cost=1.04..1.07 rows=1 width=12) -> WindowAgg (cost=1.04..1.06 rows=1 width=8) Partition By: window_preds.j -> Sort (cost=1.04..1.04 rows=1 width=8) Sort Key: window_preds.j -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=8) Hash Key: window_preds.j -> Seq Scan on window_preds (cost=0.00..1.01 rows=1 width=8) -> Subquery Scan on "*SELECT* 2" (cost=1.04..1.07 rows=1 width=12) -> WindowAgg (cost=1.04..1.06 rows=1 width=8) Partition By: window_preds_1.j -> Sort (cost=1.04..1.04 rows=1 width=8) Sort Key: window_preds_1.j -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=8) Hash Key: window_preds_1.j -> Seq Scan on window_preds window_preds_1 (cost=0.00..1.01 rows=1 width=8) Optimizer: Postgres query optimizer (21 rows) insert into window_preds with CTE as (select i, row_number() over (partition by j) j from window_preds union all select i, row_number() over (partition by j) from window_preds) select * from cte where j = 1; -- qual k = 1 should be pushed down explain select k from ( select k from (select row_number() over() as k from window_preds) f union all select 1::bigint as k from window_preds) as t where k = 1; QUERY PLAN ---------------------------------------------------------------------------------------------- Append (cost=0.00..2.08 rows=2 width=8) -> Subquery Scan on f (cost=0.00..1.03 rows=1 width=8) Filter: f.k = 1 -> WindowAgg (cost=0.00..1.02 rows=1 width=0) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.01 rows=1 width=0) -> Seq Scan on window_preds (cost=0.00..1.01 rows=1 width=0) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.04 rows=1 width=8) -> Seq Scan on window_preds window_preds_1 (cost=0.00..1.01 rows=1 width=0) Optimizer: Postgres query optimizer (9 rows) select k from ( select k from (select row_number() over() as k from window_preds) f union all select 1::bigint as k from window_preds) as t where k = 1; k --- 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 (23 rows) explain insert into window_preds select k from ( select k from (select row_number() over() as k from window_preds) f union all select 1::bigint as k from window_preds) as t where k = 1; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- Insert on window_preds (cost=0.00..2.11 rows=1 width=8) -> Redistribute Motion 1:3 (slice3; segments: 1) (cost=0.00..2.11 rows=2 width=8) Hash Key: (t.k::integer) -> Subquery Scan on t (cost=0.00..2.11 rows=2 width=8) -> Append (cost=0.00..2.08 rows=2 width=8) -> Subquery Scan on f (cost=0.00..1.03 rows=1 width=8) Filter: f.k = 1 -> WindowAgg (cost=0.00..1.02 rows=1 width=0) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.01 rows=1 width=0) -> Seq Scan on window_preds window_preds_1 (cost=0.00..1.01 rows=1 width=0) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.04 rows=1 width=8) -> Seq Scan on window_preds window_preds_2 (cost=0.00..1.01 rows=1 width=0) Optimizer: Postgres query optimizer (13 rows) insert into window_preds select k from ( select k from (select row_number() over() as k from window_preds) f union all select 1::bigint as k from window_preds) as t where k = 1; explain with CTE as (select i, row_number() over (partition by j) j from window_preds union all select i, row_number() over (partition by j) from window_preds) select * from cte where i = 1; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..0.04 rows=1 width=12) -> Subquery Scan on cte (cost=0.00..0.04 rows=1 width=12) Filter: cte.i = 1 -> Append (cost=1.04..2.14 rows=1 width=12) -> Subquery Scan on "*SELECT* 1" (cost=1.04..1.07 rows=1 width=12) -> WindowAgg (cost=1.04..1.06 rows=1 width=8) Partition By: window_preds.j -> Sort (cost=1.04..1.04 rows=1 width=8) Sort Key: window_preds.j -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=8) Hash Key: window_preds.j -> Seq Scan on window_preds (cost=0.00..1.01 rows=1 width=8) -> Subquery Scan on "*SELECT* 2" (cost=1.04..1.07 rows=1 width=12) -> WindowAgg (cost=1.04..1.06 rows=1 width=8) Partition By: window_preds_1.j -> Sort (cost=1.04..1.04 rows=1 width=8) Sort Key: window_preds_1.j -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=8) Hash Key: window_preds_1.j -> Seq Scan on window_preds window_preds_1 (cost=0.00..1.01 rows=1 width=8) Optimizer: Postgres query optimizer (21 rows) insert into window_preds with CTE as (select i, row_number() over (partition by j) j from window_preds union all select i, row_number() over (partition by j) from window_preds) select * from cte where i = 1; -- -- Tests for DISTINCT-qualified window aggregates -- -- This is a GPDB extension, not implemented in PostgreSQL. -- select dt, pn, count(distinct pn) over (partition by dt) from sale; dt | pn | count ------------+-----+------- 01-01-1401 | 100 | 1 03-01-1401 | 200 | 1 04-01-1401 | 200 | 1 05-01-1401 | 100 | 1 05-02-1401 | 300 | 1 06-01-1401 | 400 | 5 06-01-1401 | 400 | 5 06-01-1401 | 500 | 5 06-01-1401 | 500 | 5 06-01-1401 | 600 | 5 06-01-1401 | 700 | 5 06-01-1401 | 800 | 5 (12 rows) select dt, pn, count(distinct pn) over (partition by dt), sum(distinct pn) over (partition by dt) from sale; dt | pn | count | sum ------------+-----+-------+------ 01-01-1401 | 100 | 1 | 100 03-01-1401 | 200 | 1 | 200 04-01-1401 | 200 | 1 | 200 05-01-1401 | 100 | 1 | 100 05-02-1401 | 300 | 1 | 300 06-01-1401 | 400 | 5 | 3000 06-01-1401 | 400 | 5 | 3000 06-01-1401 | 500 | 5 | 3000 06-01-1401 | 500 | 5 | 3000 06-01-1401 | 600 | 5 | 3000 06-01-1401 | 700 | 5 | 3000 06-01-1401 | 800 | 5 | 3000 (12 rows) select dt, pn, sum(distinct pn) over (partition by dt), sum(pn) over (partition by dt) from sale; dt | pn | sum | sum ------------+-----+------+------ 01-01-1401 | 100 | 100 | 100 03-01-1401 | 200 | 200 | 200 04-01-1401 | 200 | 200 | 200 05-01-1401 | 100 | 100 | 100 05-02-1401 | 300 | 300 | 300 06-01-1401 | 400 | 3000 | 3900 06-01-1401 | 400 | 3000 | 3900 06-01-1401 | 500 | 3000 | 3900 06-01-1401 | 500 | 3000 | 3900 06-01-1401 | 600 | 3000 | 3900 06-01-1401 | 700 | 3000 | 3900 06-01-1401 | 800 | 3000 | 3900 (12 rows) -- Also test with a pass-by-ref type, to make sure we don't get confused with memory contexts. select pcolor, pname, count(distinct pname) over (partition by pcolor) from product; pcolor | pname | count -----------+-----------+------- Black | Dream | 2 Black | Sword | 2 Chocolate | Donuts | 1 Clear | Justice | 1 Grey | Castle | 3 Grey | Fries | 3 Grey | Hamburger | 3 Plain | Donuts | 1 (8 rows) -- Disallowed or not-implemented cases select dt, pn, count(distinct pn) over (partition by pn order by dt) from sale; ERROR: DISTINCT cannot be used with window specification containing an ORDER BY clause LINE 1: select dt, pn, count(distinct pn) over (partition by pn orde... ^ select dt, pn, count(distinct pn) over (partition by pn rows unbounded preceding ) from sale; ERROR: DISTINCT cannot be used with window specification containing a framing clause LINE 1: select dt, pn, count(distinct pn) over (partition by pn rows... ^ select dt, pn, count(distinct pn) over (partition by pn rows between unbounded preceding and unbounded following ) from sale; ERROR: DISTINCT cannot be used with window specification containing a framing clause LINE 1: select dt, pn, count(distinct pn) over (partition by pn rows... ^ -- not supported with true window functions. select dt, pn, lead(distinct pn) over (partition by pn) from sale; ERROR: DISTINCT is not implemented for window functions LINE 1: select dt, pn, lead(distinct pn) over (partition by pn) from... ^ -- not supported with aggregates with multiple arguments. select dt, pn, corr(distinct pn, pn) over (partition by dt), sum(pn) over (partition by dt) from sale; ERROR: DISTINCT is supported only for single-argument window aggregates -- Test deparsing (for \d+ and pg_dump) create view distinct_windowagg_view as select sum(distinct g/2) OVER (partition by g/4) from generate_series (1, 5) g; \d+ distinct_windowagg_view View "olap_window_seq.distinct_windowagg_view" Column | Type | Modifiers | Storage | Description --------+--------+-----------+---------+------------- sum | bigint | | plain | View definition: SELECT sum(DISTINCT g.g / 2) OVER (PARTITION BY g.g / 4) AS sum FROM generate_series(1, 5) g(g); -- End of Test