window.sql 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. --
  2. -- WINDOW FUNCTIONS
  3. --
  4. CREATE TEMPORARY TABLE empsalary (
  5. depname varchar,
  6. empno bigint,
  7. salary int,
  8. enroll_date date
  9. );
  10. INSERT INTO empsalary VALUES
  11. ('develop', 10, 5200, '2007-08-01'),
  12. ('sales', 1, 5000, '2006-10-01'),
  13. ('personnel', 5, 3500, '2007-12-10'),
  14. ('sales', 4, 4800, '2007-08-08'),
  15. ('personnel', 2, 3900, '2006-12-23'),
  16. ('develop', 7, 4200, '2008-01-01'),
  17. ('develop', 9, 4500, '2008-01-01'),
  18. ('sales', 3, 4800, '2007-08-01'),
  19. ('develop', 8, 6000, '2006-10-01'),
  20. ('develop', 11, 5200, '2007-08-15');
  21. -- empty window specification
  22. SELECT COUNT(*) OVER () FROM tenk1 WHERE unique2 < 10;
  23. SELECT COUNT(*) OVER w FROM tenk1 WHERE unique2 < 10 WINDOW w AS ();
  24. -- no window operation
  25. SELECT four FROM tenk1 WHERE FALSE WINDOW w AS (PARTITION BY ten);
  26. SELECT row_number() OVER (ORDER BY unique2) FROM tenk1 WHERE unique2 < 10;
  27. SELECT count(*) OVER (PARTITION BY four), four FROM (SELECT * FROM tenk1 WHERE two = 1)s WHERE unique2 < 10;
  28. -- opexpr with different windows evaluation.
  29. SELECT * FROM(
  30. SELECT count(*) OVER (PARTITION BY four ORDER BY ten) +
  31. sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS total,
  32. count(*) OVER (PARTITION BY four ORDER BY ten) AS fourcount,
  33. sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS twosum
  34. FROM tenk1
  35. )sub
  36. WHERE total <> fourcount + twosum;
  37. -- identical windows with different names
  38. SELECT sum(salary) OVER w1, count(*) OVER w2
  39. FROM empsalary WINDOW w1 AS (ORDER BY salary), w2 AS (ORDER BY salary);
  40. -- empty table
  41. SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 WHERE FALSE)s;
  42. -- window function with ORDER BY an expression involving aggregates (9.1 bug)
  43. select ten,
  44. sum(unique1) + sum(unique2) as res,
  45. rank() over (order by sum(unique1) + sum(unique2)) as rank
  46. from tenk1
  47. group by ten order by ten;
  48. SELECT sum(unique1) over (rows between current row and unbounded following),
  49. unique1, four
  50. FROM tenk1 WHERE unique1 < 10;
  51. SELECT sum(unique1) over (rows between 2 preceding and 2 following),
  52. unique1, four
  53. FROM tenk1 WHERE unique1 < 10;
  54. SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude no others),
  55. unique1, four
  56. FROM tenk1 WHERE unique1 < 10;
  57. SELECT sum(unique1) over (rows between 2 preceding and 1 preceding),
  58. unique1, four
  59. FROM tenk1 WHERE unique1 < 10;
  60. SELECT sum(unique1) over (rows between 1 following and 3 following),
  61. unique1, four
  62. FROM tenk1 WHERE unique1 < 10;
  63. SELECT sum(unique1) over (rows between unbounded preceding and 1 following),
  64. unique1, four
  65. FROM tenk1 WHERE unique1 < 10;
  66. -- Test in_range for other numeric datatypes
  67. create temp table numerics(
  68. id int,
  69. f_float4 float4,
  70. f_float8 float8,
  71. f_numeric numeric
  72. );
  73. insert into numerics values
  74. (0, '-infinity', '-infinity', '-infinity'),
  75. (1, -3, -3, -3),
  76. (2, -1, -1, -1),
  77. (3, 0, 0, 0),
  78. (4, 1.1, 1.1, 1.1),
  79. (5, 1.12, 1.12, 1.12),
  80. (6, 2, 2, 2),
  81. (7, 100, 100, 100),
  82. (8, 'infinity', 'infinity', 'infinity'),
  83. (9, 'NaN', 'NaN', 'NaN');
  84. -- Test in_range for other datetime datatypes
  85. create temp table datetimes(
  86. id int,
  87. f_time time,
  88. f_timetz timetz,
  89. f_interval interval,
  90. f_timestamptz timestamptz,
  91. f_timestamp timestamp
  92. );
  93. -- Show differences in offset interpretation between ROWS, RANGE, and GROUPS
  94. WITH cte (x) AS (
  95. SELECT * FROM generate_series(1, 35, 2)
  96. )
  97. SELECT x, (sum(x) over w)
  98. FROM cte
  99. WINDOW w AS (ORDER BY x rows between 1 preceding and 1 following);
  100. WITH cte (x) AS (
  101. select 1 union all select 1 union all select 1 union all
  102. SELECT * FROM generate_series(5, 49, 2)
  103. )
  104. SELECT x, (sum(x) over w)
  105. FROM cte
  106. WINDOW w AS (ORDER BY x rows between 1 preceding and 1 following);
  107. -- with UNION
  108. SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 UNION ALL SELECT * FROM tenk2)s LIMIT 0;
  109. -- check some degenerate cases
  110. create temp table t1 (f1 int, f2 int8);
  111. insert into t1 values (1,1),(1,2),(2,2);
  112. -- ordering by a non-integer constant is allowed
  113. SELECT rank() OVER (ORDER BY length('abc'));
  114. SELECT * FROM rank() OVER (ORDER BY random());
  115. SELECT rank() OVER (PARTITION BY four, ORDER BY ten) FROM tenk1;
  116. -- cleanup
  117. DROP TABLE empsalary;
  118. --
  119. -- Test various built-in aggregates that have moving-aggregate support
  120. --
  121. -- test inverse transition functions handle NULLs properly
  122. SELECT i,AVG(v::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  123. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  124. SELECT i,AVG(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  125. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  126. SELECT i,AVG(v::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  127. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  128. SELECT i,AVG(v::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  129. FROM (VALUES(1,1.5),(2,2.5),(3,NULL),(4,NULL)) t(i,v);
  130. SELECT i,SUM(v::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  131. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  132. SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  133. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  134. SELECT i,SUM(v::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  135. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  136. SELECT i,SUM(v::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  137. FROM (VALUES(1,1.1),(2,2.2),(3,NULL),(4,NULL)) t(i,v);
  138. SELECT SUM(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  139. FROM (VALUES(1,1.01),(2,2),(3,3)) v(i,n);
  140. SELECT i,COUNT(*) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  141. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  142. SELECT VAR_SAMP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  143. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  144. SELECT VAR_SAMP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  145. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  146. SELECT VAR_SAMP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  147. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  148. SELECT VAR_SAMP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  149. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  150. SELECT VARIANCE(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  151. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  152. SELECT VARIANCE(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  153. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  154. SELECT VARIANCE(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  155. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  156. SELECT VARIANCE(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  157. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  158. SELECT STDDEV_SAMP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  159. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  160. SELECT STDDEV_SAMP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  161. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  162. SELECT STDDEV_SAMP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  163. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  164. SELECT STDDEV_SAMP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  165. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  166. SELECT STDDEV(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  167. FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  168. SELECT STDDEV(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  169. FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  170. SELECT STDDEV(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  171. FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  172. SELECT STDDEV(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  173. FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  174. -- test that inverse transition functions work with various frame options
  175. SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND CURRENT ROW)
  176. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  177. SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
  178. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  179. SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
  180. FROM (VALUES(1,1),(2,2),(3,3),(4,4)) t(i,v);
  181. -- ensure aggregate over numeric properly recovers from NaN values
  182. SELECT a, b,
  183. SUM(b) OVER(ORDER BY A ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
  184. FROM (VALUES(1,1::numeric),(2,2),(3,'NaN'),(4,3),(5,4)) t(a,b);
  185. -- It might be tempting for someone to add an inverse trans function for
  186. -- float and double precision. This should not be done as it can give incorrect
  187. -- results. This test should fail if anyone ever does this without thinking too
  188. -- hard about it.
  189. SELECT to_char(SUM(n::float8) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),'999999999999999999999D9')
  190. FROM (VALUES(1,1e20),(2,1)) n(i,n);
  191. SELECT i, b, bool_and(b) OVER w, bool_or(b) OVER w
  192. FROM (VALUES (1,true), (2,true), (3,false), (4,false), (5,true)) v(i,b)
  193. WINDOW w AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING);