window.sql 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
  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. SELECT depname, empno, salary, sum(salary) OVER (PARTITION BY depname) FROM empsalary ORDER BY depname, salary;
  22. SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary) FROM empsalary;
  23. -- with GROUP BY
  24. SELECT four, ten, SUM(SUM(four)) OVER (PARTITION BY four), AVG(ten) FROM tenk1
  25. GROUP BY four, ten ORDER BY four, ten;
  26. SELECT depname, empno, salary, sum(salary) OVER w FROM empsalary WINDOW w AS (PARTITION BY depname);
  27. SELECT depname, empno, salary, rank() OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary) ORDER BY rank() OVER w;
  28. -- empty window specification
  29. SELECT COUNT(*) OVER () FROM tenk1 WHERE unique2 < 10;
  30. SELECT COUNT(*) OVER w FROM tenk1 WHERE unique2 < 10 WINDOW w AS ();
  31. -- no window operation
  32. SELECT four FROM tenk1 WHERE FALSE WINDOW w AS (PARTITION BY ten);
  33. -- cumulative aggregate
  34. SELECT sum(four) OVER (PARTITION BY ten ORDER BY unique2) AS sum_1, ten, four FROM tenk1 WHERE unique2 < 10;
  35. SELECT row_number() OVER (ORDER BY unique2) FROM tenk1 WHERE unique2 < 10;
  36. SELECT rank() OVER (PARTITION BY four ORDER BY ten) AS rank_1, ten, four FROM tenk1 WHERE unique2 < 10;
  37. SELECT dense_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  38. SELECT percent_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  39. SELECT cume_dist() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  40. SELECT ntile(3) OVER (ORDER BY ten, four), ten, four FROM tenk1 WHERE unique2 < 10;
  41. SELECT ntile(NULL) OVER (ORDER BY ten, four), ten, four FROM tenk1 LIMIT 2;
  42. SELECT lag(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  43. SELECT lag(ten, four) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  44. SELECT lag(ten, four, 0) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  45. SELECT lag(ten, four, 0.7) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten;
  46. SELECT lead(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  47. SELECT lead(ten * 2, 1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  48. SELECT lead(ten * 2, 1, -1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  49. SELECT lead(ten * 2, 1, -1.4) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten;
  50. SELECT first_value(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  51. -- last_value returns the last row of the frame, which is CURRENT ROW in ORDER BY window.
  52. SELECT last_value(four) OVER (ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10;
  53. SELECT last_value(ten) OVER (PARTITION BY four), ten, four FROM
  54. (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten)s
  55. ORDER BY four, ten;
  56. SELECT nth_value(ten, four + 1) OVER (PARTITION BY four), ten, four
  57. FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten)s;
  58. SELECT ten, two, sum(hundred) AS gsum, sum(sum(hundred)) OVER (PARTITION BY two ORDER BY ten) AS wsum
  59. FROM tenk1 GROUP BY ten, two;
  60. SELECT count(*) OVER (PARTITION BY four), four FROM (SELECT * FROM tenk1 WHERE two = 1)s WHERE unique2 < 10;
  61. SELECT (count(*) OVER (PARTITION BY four ORDER BY ten) +
  62. sum(hundred) OVER (PARTITION BY four ORDER BY ten))::varchar AS cntsum
  63. FROM tenk1 WHERE unique2 < 10;
  64. -- opexpr with different windows evaluation.
  65. SELECT * FROM(
  66. SELECT count(*) OVER (PARTITION BY four ORDER BY ten) +
  67. sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS total,
  68. count(*) OVER (PARTITION BY four ORDER BY ten) AS fourcount,
  69. sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS twosum
  70. FROM tenk1
  71. )sub
  72. WHERE total <> fourcount + twosum;
  73. SELECT avg(four) OVER (PARTITION BY four ORDER BY thousand / 100) FROM tenk1 WHERE unique2 < 10;
  74. SELECT ten, two, sum(hundred) AS gsum, sum(sum(hundred)) OVER win AS wsum
  75. FROM tenk1 GROUP BY ten, two WINDOW win AS (PARTITION BY two ORDER BY ten);
  76. -- more than one window with GROUP BY
  77. SELECT sum(salary),
  78. row_number() OVER (ORDER BY depname),
  79. sum(sum(salary)) OVER (ORDER BY depname DESC)
  80. FROM empsalary GROUP BY depname;
  81. -- identical windows with different names
  82. SELECT sum(salary) OVER w1, count(*) OVER w2
  83. FROM empsalary WINDOW w1 AS (ORDER BY salary), w2 AS (ORDER BY salary);
  84. -- subplan
  85. SELECT lead(ten, (SELECT two FROM tenk1 WHERE s.unique2 = unique2)) OVER (PARTITION BY four ORDER BY ten)
  86. FROM tenk1 s WHERE unique2 < 10;
  87. -- empty table
  88. SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 WHERE FALSE)s;
  89. -- mixture of agg/wfunc in the same window
  90. SELECT sum(salary) OVER w, rank() OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);
  91. -- strict aggs
  92. SELECT empno, depname, salary, bonus, depadj, MIN(bonus) OVER (ORDER BY empno), MAX(depadj) OVER () FROM(
  93. SELECT *,
  94. CASE WHEN enroll_date < '2008-01-01' THEN 2008 - extract(YEAR FROM enroll_date) END * 500 AS bonus,
  95. CASE WHEN
  96. AVG(salary) OVER (PARTITION BY depname) < salary
  97. THEN 200 END AS depadj FROM empsalary
  98. )s;
  99. -- window function over ungrouped agg over empty row set (bug before 9.1)
  100. SELECT SUM(COUNT(f1)) OVER () FROM int4_tbl WHERE f1=42;
  101. -- window function with ORDER BY an expression involving aggregates (9.1 bug)
  102. select ten,
  103. sum(unique1) + sum(unique2) as res,
  104. rank() over (order by sum(unique1) + sum(unique2)) as rank
  105. from tenk1
  106. group by ten order by ten;
  107. -- window and aggregate with GROUP BY expression (9.2 bug)
  108. explain (costs off)
  109. select first_value(max(x)) over (), y
  110. from (select unique1 as x, ten+four as y from tenk1) ss
  111. group by y;
  112. -- test non-default frame specifications
  113. SELECT four, ten,
  114. sum(ten) over (partition by four order by ten),
  115. last_value(ten) over (partition by four order by ten)
  116. FROM (select distinct ten, four from tenk1) ss;
  117. SELECT four, ten,
  118. sum(ten) over (partition by four order by ten range between unbounded preceding and current row),
  119. last_value(ten) over (partition by four order by ten range between unbounded preceding and current row)
  120. FROM (select distinct ten, four from tenk1) ss;
  121. SELECT four, ten,
  122. sum(ten) over (partition by four order by ten range between unbounded preceding and unbounded following),
  123. last_value(ten) over (partition by four order by ten range between unbounded preceding and unbounded following)
  124. FROM (select distinct ten, four from tenk1) ss;
  125. SELECT four, ten/4 as two,
  126. sum(ten/4) over (partition by four order by ten/4 range between unbounded preceding and current row),
  127. last_value(ten/4) over (partition by four order by ten/4 range between unbounded preceding and current row)
  128. FROM (select distinct ten, four from tenk1) ss;
  129. SELECT four, ten/4 as two,
  130. sum(ten/4) over (partition by four order by ten/4 rows between unbounded preceding and current row),
  131. last_value(ten/4) over (partition by four order by ten/4 rows between unbounded preceding and current row)
  132. FROM (select distinct ten, four from tenk1) ss;
  133. SELECT sum(unique1) over (order by four range between current row and unbounded following),
  134. unique1, four
  135. FROM tenk1 WHERE unique1 < 10;
  136. SELECT sum(unique1) over (rows between current row and unbounded following),
  137. unique1, four
  138. FROM tenk1 WHERE unique1 < 10;
  139. SELECT sum(unique1) over (rows between 2 preceding and 2 following),
  140. unique1, four
  141. FROM tenk1 WHERE unique1 < 10;
  142. SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude no others),
  143. unique1, four
  144. FROM tenk1 WHERE unique1 < 10;
  145. SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude current row),
  146. unique1, four
  147. FROM tenk1 WHERE unique1 < 10;
  148. SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude group),
  149. unique1, four
  150. FROM tenk1 WHERE unique1 < 10;
  151. SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude ties),
  152. unique1, four
  153. FROM tenk1 WHERE unique1 < 10;
  154. SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude current row),
  155. unique1, four
  156. FROM tenk1 WHERE unique1 < 10;
  157. SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude group),
  158. unique1, four
  159. FROM tenk1 WHERE unique1 < 10;
  160. SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude ties),
  161. unique1, four
  162. FROM tenk1 WHERE unique1 < 10;
  163. SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude current row),
  164. unique1, four
  165. FROM tenk1 WHERE unique1 < 10;
  166. SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude group),
  167. unique1, four
  168. FROM tenk1 WHERE unique1 < 10;
  169. SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude ties),
  170. unique1, four
  171. FROM tenk1 WHERE unique1 < 10;
  172. SELECT sum(unique1) over (rows between 2 preceding and 1 preceding),
  173. unique1, four
  174. FROM tenk1 WHERE unique1 < 10;
  175. SELECT sum(unique1) over (rows between 1 following and 3 following),
  176. unique1, four
  177. FROM tenk1 WHERE unique1 < 10;
  178. SELECT sum(unique1) over (rows between unbounded preceding and 1 following),
  179. unique1, four
  180. FROM tenk1 WHERE unique1 < 10;
  181. SELECT sum(unique1) over (w range between current row and unbounded following),
  182. unique1, four
  183. FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four);
  184. SELECT sum(unique1) over (w range between unbounded preceding and current row exclude current row),
  185. unique1, four
  186. FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four);
  187. SELECT sum(unique1) over (w range between unbounded preceding and current row exclude group),
  188. unique1, four
  189. FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four);
  190. SELECT sum(unique1) over (w range between unbounded preceding and current row exclude ties),
  191. unique1, four
  192. FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four);
  193. SELECT first_value(unique1) over w,
  194. nth_value(unique1, 2) over w AS nth_2,
  195. last_value(unique1) over w, unique1, four
  196. FROM tenk1 WHERE unique1 < 10
  197. WINDOW w AS (order by four range between current row and unbounded following);
  198. SELECT sum(unique1) over
  199. (order by unique1
  200. rows (SELECT unique1 FROM tenk1 ORDER BY unique1 LIMIT 1) + 1 PRECEDING),
  201. unique1
  202. FROM tenk1 WHERE unique1 < 10;
  203. CREATE TEMP VIEW v_window AS
  204. SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following) as sum_rows
  205. FROM generate_series(1, 10) i;
  206. SELECT * FROM v_window;
  207. SELECT pg_get_viewdef('v_window');
  208. CREATE OR REPLACE TEMP VIEW v_window AS
  209. SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following
  210. exclude current row) as sum_rows FROM generate_series(1, 10) i;
  211. SELECT * FROM v_window;
  212. SELECT pg_get_viewdef('v_window');
  213. CREATE OR REPLACE TEMP VIEW v_window AS
  214. SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following
  215. exclude group) as sum_rows FROM generate_series(1, 10) i;
  216. SELECT * FROM v_window;
  217. SELECT pg_get_viewdef('v_window');
  218. CREATE OR REPLACE TEMP VIEW v_window AS
  219. SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following
  220. exclude ties) as sum_rows FROM generate_series(1, 10) i;
  221. SELECT * FROM v_window;
  222. SELECT pg_get_viewdef('v_window');
  223. CREATE OR REPLACE TEMP VIEW v_window AS
  224. SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following
  225. exclude no others) as sum_rows FROM generate_series(1, 10) i;
  226. SELECT * FROM v_window;
  227. SELECT pg_get_viewdef('v_window');
  228. CREATE OR REPLACE TEMP VIEW v_window AS
  229. SELECT i, sum(i) over (order by i groups between 1 preceding and 1 following) as sum_rows FROM generate_series(1, 10) i;
  230. SELECT * FROM v_window;
  231. SELECT pg_get_viewdef('v_window');
  232. DROP VIEW v_window;
  233. CREATE TEMP VIEW v_window AS
  234. SELECT i, min(i) over (order by i range between '1 day' preceding and '10 days' following) as min_i
  235. FROM generate_series(now(), now()+'100 days'::interval, '1 hour') i;
  236. SELECT pg_get_viewdef('v_window');
  237. -- RANGE offset PRECEDING/FOLLOWING tests
  238. SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding),
  239. unique1, four
  240. FROM tenk1 WHERE unique1 < 10;
  241. SELECT sum(unique1) over (order by four desc range between 2::int8 preceding and 1::int2 preceding),
  242. unique1, four
  243. FROM tenk1 WHERE unique1 < 10;
  244. SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude no others),
  245. unique1, four
  246. FROM tenk1 WHERE unique1 < 10;
  247. SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude current row),
  248. unique1, four
  249. FROM tenk1 WHERE unique1 < 10;
  250. SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude group),
  251. unique1, four
  252. FROM tenk1 WHERE unique1 < 10;
  253. SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude ties),
  254. unique1, four
  255. FROM tenk1 WHERE unique1 < 10;
  256. SELECT sum(unique1) over (order by four range between 2::int8 preceding and 6::int2 following exclude ties),
  257. unique1, four
  258. FROM tenk1 WHERE unique1 < 10;
  259. SELECT sum(unique1) over (order by four range between 2::int8 preceding and 6::int2 following exclude group),
  260. unique1, four
  261. FROM tenk1 WHERE unique1 < 10;
  262. SELECT sum(unique1) over (partition by four order by unique1 range between 5::int8 preceding and 6::int2 following),
  263. unique1, four
  264. FROM tenk1 WHERE unique1 < 10;
  265. SELECT sum(unique1) over (partition by four order by unique1 range between 5::int8 preceding and 6::int2 following
  266. exclude current row),unique1, four
  267. FROM tenk1 WHERE unique1 < 10;
  268. select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following),
  269. salary, enroll_date from empsalary;
  270. select sum(salary) over (order by enroll_date desc range between '1 year'::interval preceding and '1 year'::interval following),
  271. salary, enroll_date from empsalary;
  272. select sum(salary) over (order by enroll_date desc range between '1 year'::interval following and '1 year'::interval following),
  273. salary, enroll_date from empsalary;
  274. select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following
  275. exclude current row), salary, enroll_date from empsalary;
  276. select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following
  277. exclude group), salary, enroll_date from empsalary;
  278. select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following
  279. exclude ties), salary, enroll_date from empsalary;
  280. select first_value(salary) over(order by salary range between 1000 preceding and 1000 following),
  281. lead(salary) over(order by salary range between 1000 preceding and 1000 following),
  282. nth_value(salary, 1) over(order by salary range between 1000 preceding and 1000 following),
  283. salary from empsalary;
  284. select last_value(salary) over(order by salary range between 1000 preceding and 1000 following),
  285. lag(salary) over(order by salary range between 1000 preceding and 1000 following),
  286. salary from empsalary;
  287. select first_value(salary) over(order by salary range between 1000 following and 3000 following
  288. exclude current row),
  289. lead(salary) over(order by salary range between 1000 following and 3000 following exclude ties),
  290. nth_value(salary, 1) over(order by salary range between 1000 following and 3000 following
  291. exclude ties),
  292. salary from empsalary;
  293. select last_value(salary) over(order by salary range between 1000 following and 3000 following
  294. exclude group),
  295. lag(salary) over(order by salary range between 1000 following and 3000 following exclude group),
  296. salary from empsalary;
  297. select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following
  298. exclude ties),
  299. last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following),
  300. salary, enroll_date from empsalary;
  301. select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following
  302. exclude ties),
  303. last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following
  304. exclude ties),
  305. salary, enroll_date from empsalary;
  306. select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following
  307. exclude group),
  308. last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following
  309. exclude group),
  310. salary, enroll_date from empsalary;
  311. select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following
  312. exclude current row),
  313. last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following
  314. exclude current row),
  315. salary, enroll_date from empsalary;
  316. -- RANGE offset PRECEDING/FOLLOWING with null values
  317. select x, y,
  318. first_value(y) over w,
  319. last_value(y) over w
  320. from
  321. (select x, x as y from generate_series(1,5) as x
  322. union all select null, 42
  323. union all select null, 43) ss
  324. window w as
  325. (order by x asc nulls first range between 2 preceding and 2 following);
  326. select x, y,
  327. first_value(y) over w,
  328. last_value(y) over w
  329. from
  330. (select x, x as y from generate_series(1,5) as x
  331. union all select null, 42
  332. union all select null, 43) ss
  333. window w as
  334. (order by x asc nulls last range between 2 preceding and 2 following);
  335. select x, y,
  336. first_value(y) over w,
  337. last_value(y) over w
  338. from
  339. (select x, x as y from generate_series(1,5) as x
  340. union all select null, 42
  341. union all select null, 43) ss
  342. window w as
  343. (order by x desc nulls first range between 2 preceding and 2 following);
  344. select x, y,
  345. first_value(y) over w,
  346. last_value(y) over w
  347. from
  348. (select x, x as y from generate_series(1,5) as x
  349. union all select null, 42
  350. union all select null, 43) ss
  351. window w as
  352. (order by x desc nulls last range between 2 preceding and 2 following);
  353. -- Check overflow behavior for various integer sizes
  354. select x, last_value(x) over (order by x::smallint range between current row and 2147450884 following)
  355. from generate_series(32764, 32766) x;
  356. select x, last_value(x) over (order by x::smallint desc range between current row and 2147450885 following)
  357. from generate_series(-32766, -32764) x;
  358. select x, last_value(x) over (order by x range between current row and 4 following)
  359. from generate_series(2147483644, 2147483646) x;
  360. select x, last_value(x) over (order by x desc range between current row and 5 following)
  361. from generate_series(-2147483646, -2147483644) x;
  362. select x, last_value(x) over (order by x range between current row and 4 following)
  363. from generate_series(9223372036854775804, 9223372036854775806) x;
  364. select x, last_value(x) over (order by x desc range between current row and 5 following)
  365. from generate_series(-9223372036854775806, -9223372036854775804) x;
  366. -- Test in_range for other numeric datatypes
  367. create temp table numerics(
  368. id int,
  369. f_float4 float4,
  370. f_float8 float8,
  371. f_numeric numeric
  372. );
  373. insert into numerics values
  374. (0, '-infinity', '-infinity', '-infinity'),
  375. (1, -3, -3, -3),
  376. (2, -1, -1, -1),
  377. (3, 0, 0, 0),
  378. (4, 1.1, 1.1, 1.1),
  379. (5, 1.12, 1.12, 1.12),
  380. (6, 2, 2, 2),
  381. (7, 100, 100, 100),
  382. (8, 'infinity', 'infinity', 'infinity'),
  383. (9, 'NaN', 'NaN', 'NaN');
  384. select id, f_float4, first_value(id) over w, last_value(id) over w
  385. from numerics
  386. window w as (order by f_float4 range between
  387. 1 preceding and 1 following);
  388. select id, f_float4, first_value(id) over w, last_value(id) over w
  389. from numerics
  390. window w as (order by f_float4 range between
  391. 1 preceding and 1.1::float4 following);
  392. select id, f_float4, first_value(id) over w, last_value(id) over w
  393. from numerics
  394. window w as (order by f_float4 range between
  395. 'inf' preceding and 'inf' following);
  396. select id, f_float4, first_value(id) over w, last_value(id) over w
  397. from numerics
  398. window w as (order by f_float4 range between
  399. 'inf' preceding and 'inf' preceding);
  400. select id, f_float4, first_value(id) over w, last_value(id) over w
  401. from numerics
  402. window w as (order by f_float4 range between
  403. 'inf' following and 'inf' following);
  404. select id, f_float4, first_value(id) over w, last_value(id) over w
  405. from numerics
  406. window w as (order by f_float4 range between
  407. 1.1 preceding and 'NaN' following); -- error, NaN disallowed
  408. select id, f_float8, first_value(id) over w, last_value(id) over w
  409. from numerics
  410. window w as (order by f_float8 range between
  411. 1 preceding and 1 following);
  412. select id, f_float8, first_value(id) over w, last_value(id) over w
  413. from numerics
  414. window w as (order by f_float8 range between
  415. 1 preceding and 1.1::float8 following);
  416. select id, f_float8, first_value(id) over w, last_value(id) over w
  417. from numerics
  418. window w as (order by f_float8 range between
  419. 'inf' preceding and 'inf' following);
  420. select id, f_float8, first_value(id) over w, last_value(id) over w
  421. from numerics
  422. window w as (order by f_float8 range between
  423. 'inf' preceding and 'inf' preceding);
  424. select id, f_float8, first_value(id) over w, last_value(id) over w
  425. from numerics
  426. window w as (order by f_float8 range between
  427. 'inf' following and 'inf' following);
  428. select id, f_float8, first_value(id) over w, last_value(id) over w
  429. from numerics
  430. window w as (order by f_float8 range between
  431. 1.1 preceding and 'NaN' following); -- error, NaN disallowed
  432. select id, f_numeric, first_value(id) over w, last_value(id) over w
  433. from numerics
  434. window w as (order by f_numeric range between
  435. 1 preceding and 1 following);
  436. select id, f_numeric, first_value(id) over w, last_value(id) over w
  437. from numerics
  438. window w as (order by f_numeric range between
  439. 1 preceding and 1.1::numeric following);
  440. select id, f_numeric, first_value(id) over w, last_value(id) over w
  441. from numerics
  442. window w as (order by f_numeric range between
  443. 1 preceding and 1.1::float8 following); -- currently unsupported
  444. select id, f_numeric, first_value(id) over w, last_value(id) over w
  445. from numerics
  446. window w as (order by f_numeric range between
  447. 'inf' preceding and 'inf' following);
  448. select id, f_numeric, first_value(id) over w, last_value(id) over w
  449. from numerics
  450. window w as (order by f_numeric range between
  451. 'inf' preceding and 'inf' preceding);
  452. select id, f_numeric, first_value(id) over w, last_value(id) over w
  453. from numerics
  454. window w as (order by f_numeric range between
  455. 'inf' following and 'inf' following);
  456. select id, f_numeric, first_value(id) over w, last_value(id) over w
  457. from numerics
  458. window w as (order by f_numeric range between
  459. 1.1 preceding and 'NaN' following); -- error, NaN disallowed
  460. -- Test in_range for other datetime datatypes
  461. create temp table datetimes(
  462. id int,
  463. f_time time,
  464. f_timetz timetz,
  465. f_interval interval,
  466. f_timestamptz timestamptz,
  467. f_timestamp timestamp
  468. );
  469. insert into datetimes values
  470. (1, '11:00', '11:00 BST', '1 year', '2000-10-19 10:23:54+01', '2000-10-19 10:23:54'),
  471. (2, '12:00', '12:00 BST', '2 years', '2001-10-19 10:23:54+01', '2001-10-19 10:23:54'),
  472. (3, '13:00', '13:00 BST', '3 years', '2001-10-19 10:23:54+01', '2001-10-19 10:23:54'),
  473. (4, '14:00', '14:00 BST', '4 years', '2002-10-19 10:23:54+01', '2002-10-19 10:23:54'),
  474. (5, '15:00', '15:00 BST', '5 years', '2003-10-19 10:23:54+01', '2003-10-19 10:23:54'),
  475. (6, '15:00', '15:00 BST', '5 years', '2004-10-19 10:23:54+01', '2004-10-19 10:23:54'),
  476. (7, '17:00', '17:00 BST', '7 years', '2005-10-19 10:23:54+01', '2005-10-19 10:23:54'),
  477. (8, '18:00', '18:00 BST', '8 years', '2006-10-19 10:23:54+01', '2006-10-19 10:23:54'),
  478. (9, '19:00', '19:00 BST', '9 years', '2007-10-19 10:23:54+01', '2007-10-19 10:23:54'),
  479. (10, '20:00', '20:00 BST', '10 years', '2008-10-19 10:23:54+01', '2008-10-19 10:23:54');
  480. select id, f_time, first_value(id) over w, last_value(id) over w
  481. from datetimes
  482. window w as (order by f_time range between
  483. '70 min'::interval preceding and '2 hours'::interval following);
  484. select id, f_time, first_value(id) over w, last_value(id) over w
  485. from datetimes
  486. window w as (order by f_time desc range between
  487. '70 min' preceding and '2 hours' following);
  488. select id, f_timetz, first_value(id) over w, last_value(id) over w
  489. from datetimes
  490. window w as (order by f_timetz range between
  491. '70 min'::interval preceding and '2 hours'::interval following);
  492. select id, f_timetz, first_value(id) over w, last_value(id) over w
  493. from datetimes
  494. window w as (order by f_timetz desc range between
  495. '70 min' preceding and '2 hours' following);
  496. select id, f_interval, first_value(id) over w, last_value(id) over w
  497. from datetimes
  498. window w as (order by f_interval range between
  499. '1 year'::interval preceding and '1 year'::interval following);
  500. select id, f_interval, first_value(id) over w, last_value(id) over w
  501. from datetimes
  502. window w as (order by f_interval desc range between
  503. '1 year' preceding and '1 year' following);
  504. select id, f_timestamptz, first_value(id) over w, last_value(id) over w
  505. from datetimes
  506. window w as (order by f_timestamptz range between
  507. '1 year'::interval preceding and '1 year'::interval following);
  508. select id, f_timestamptz, first_value(id) over w, last_value(id) over w
  509. from datetimes
  510. window w as (order by f_timestamptz desc range between
  511. '1 year' preceding and '1 year' following);
  512. select id, f_timestamp, first_value(id) over w, last_value(id) over w
  513. from datetimes
  514. window w as (order by f_timestamp range between
  515. '1 year'::interval preceding and '1 year'::interval following);
  516. select id, f_timestamp, first_value(id) over w, last_value(id) over w
  517. from datetimes
  518. window w as (order by f_timestamp desc range between
  519. '1 year' preceding and '1 year' following);
  520. -- RANGE offset PRECEDING/FOLLOWING error cases
  521. select sum(salary) over (order by enroll_date, salary range between '1 year'::interval preceding and '2 years'::interval following
  522. exclude ties), salary, enroll_date from empsalary;
  523. select sum(salary) over (range between '1 year'::interval preceding and '2 years'::interval following
  524. exclude ties), salary, enroll_date from empsalary;
  525. select sum(salary) over (order by depname range between '1 year'::interval preceding and '2 years'::interval following
  526. exclude ties), salary, enroll_date from empsalary;
  527. select max(enroll_date) over (order by enroll_date range between 1 preceding and 2 following
  528. exclude ties), salary, enroll_date from empsalary;
  529. select max(enroll_date) over (order by salary range between -1 preceding and 2 following
  530. exclude ties), salary, enroll_date from empsalary;
  531. select max(enroll_date) over (order by salary range between 1 preceding and -2 following
  532. exclude ties), salary, enroll_date from empsalary;
  533. select max(enroll_date) over (order by salary range between '1 year'::interval preceding and '2 years'::interval following
  534. exclude ties), salary, enroll_date from empsalary;
  535. select max(enroll_date) over (order by enroll_date range between '1 year'::interval preceding and '-2 years'::interval following
  536. exclude ties), salary, enroll_date from empsalary;
  537. -- GROUPS tests
  538. SELECT sum(unique1) over (order by four groups between unbounded preceding and current row),
  539. unique1, four
  540. FROM tenk1 WHERE unique1 < 10;
  541. SELECT sum(unique1) over (order by four groups between unbounded preceding and unbounded following),
  542. unique1, four
  543. FROM tenk1 WHERE unique1 < 10;
  544. SELECT sum(unique1) over (order by four groups between current row and unbounded following),
  545. unique1, four
  546. FROM tenk1 WHERE unique1 < 10;
  547. SELECT sum(unique1) over (order by four groups between 1 preceding and unbounded following),
  548. unique1, four
  549. FROM tenk1 WHERE unique1 < 10;
  550. SELECT sum(unique1) over (order by four groups between 1 following and unbounded following),
  551. unique1, four
  552. FROM tenk1 WHERE unique1 < 10;
  553. SELECT sum(unique1) over (order by four groups between unbounded preceding and 2 following),
  554. unique1, four
  555. FROM tenk1 WHERE unique1 < 10;
  556. SELECT sum(unique1) over (order by four groups between 2 preceding and 1 preceding),
  557. unique1, four
  558. FROM tenk1 WHERE unique1 < 10;
  559. SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following),
  560. unique1, four
  561. FROM tenk1 WHERE unique1 < 10;
  562. SELECT sum(unique1) over (order by four groups between 0 preceding and 0 following),
  563. unique1, four
  564. FROM tenk1 WHERE unique1 < 10;
  565. SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following
  566. exclude current row), unique1, four
  567. FROM tenk1 WHERE unique1 < 10;
  568. SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following
  569. exclude group), unique1, four
  570. FROM tenk1 WHERE unique1 < 10;
  571. SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following
  572. exclude ties), unique1, four
  573. FROM tenk1 WHERE unique1 < 10;
  574. SELECT sum(unique1) over (partition by ten
  575. order by four groups between 0 preceding and 0 following),unique1, four, ten
  576. FROM tenk1 WHERE unique1 < 10;
  577. SELECT sum(unique1) over (partition by ten
  578. order by four groups between 0 preceding and 0 following exclude current row), unique1, four, ten
  579. FROM tenk1 WHERE unique1 < 10;
  580. SELECT sum(unique1) over (partition by ten
  581. order by four groups between 0 preceding and 0 following exclude group), unique1, four, ten
  582. FROM tenk1 WHERE unique1 < 10;
  583. SELECT sum(unique1) over (partition by ten
  584. order by four groups between 0 preceding and 0 following exclude ties), unique1, four, ten
  585. FROM tenk1 WHERE unique1 < 10;
  586. select first_value(salary) over(order by enroll_date groups between 1 preceding and 1 following),
  587. lead(salary) over(order by enroll_date groups between 1 preceding and 1 following),
  588. nth_value(salary, 1) over(order by enroll_date groups between 1 preceding and 1 following),
  589. salary, enroll_date from empsalary;
  590. select last_value(salary) over(order by enroll_date groups between 1 preceding and 1 following),
  591. lag(salary) over(order by enroll_date groups between 1 preceding and 1 following),
  592. salary, enroll_date from empsalary;
  593. select first_value(salary) over(order by enroll_date groups between 1 following and 3 following
  594. exclude current row),
  595. lead(salary) over(order by enroll_date groups between 1 following and 3 following exclude ties),
  596. nth_value(salary, 1) over(order by enroll_date groups between 1 following and 3 following
  597. exclude ties),
  598. salary, enroll_date from empsalary;
  599. select last_value(salary) over(order by enroll_date groups between 1 following and 3 following
  600. exclude group),
  601. lag(salary) over(order by enroll_date groups between 1 following and 3 following exclude group),
  602. salary, enroll_date from empsalary;
  603. -- Show differences in offset interpretation between ROWS, RANGE, and GROUPS
  604. WITH cte (x) AS (
  605. SELECT * FROM generate_series(1, 35, 2)
  606. )
  607. SELECT x, (sum(x) over w)
  608. FROM cte
  609. WINDOW w AS (ORDER BY x rows between 1 preceding and 1 following);
  610. WITH cte (x) AS (
  611. SELECT * FROM generate_series(1, 35, 2)
  612. )
  613. SELECT x, (sum(x) over w)
  614. FROM cte
  615. WINDOW w AS (ORDER BY x range between 1 preceding and 1 following);
  616. WITH cte (x) AS (
  617. SELECT * FROM generate_series(1, 35, 2)
  618. )
  619. SELECT x, (sum(x) over w)
  620. FROM cte
  621. WINDOW w AS (ORDER BY x groups between 1 preceding and 1 following);
  622. WITH cte (x) AS (
  623. select 1 union all select 1 union all select 1 union all
  624. SELECT * FROM generate_series(5, 49, 2)
  625. )
  626. SELECT x, (sum(x) over w)
  627. FROM cte
  628. WINDOW w AS (ORDER BY x rows between 1 preceding and 1 following);
  629. WITH cte (x) AS (
  630. select 1 union all select 1 union all select 1 union all
  631. SELECT * FROM generate_series(5, 49, 2)
  632. )
  633. SELECT x, (sum(x) over w)
  634. FROM cte
  635. WINDOW w AS (ORDER BY x range between 1 preceding and 1 following);
  636. WITH cte (x) AS (
  637. select 1 union all select 1 union all select 1 union all
  638. SELECT * FROM generate_series(5, 49, 2)
  639. )
  640. SELECT x, (sum(x) over w)
  641. FROM cte
  642. WINDOW w AS (ORDER BY x groups between 1 preceding and 1 following);
  643. -- with UNION
  644. SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 UNION ALL SELECT * FROM tenk2)s LIMIT 0;
  645. -- check some degenerate cases
  646. create temp table t1 (f1 int, f2 int8);
  647. insert into t1 values (1,1),(1,2),(2,2);
  648. select f1, sum(f1) over (partition by f1
  649. range between 1 preceding and 1 following)
  650. from t1 where f1 = f2; -- error, must have order by
  651. explain (costs off)
  652. select f1, sum(f1) over (partition by f1 order by f2
  653. range between 1 preceding and 1 following)
  654. from t1 where f1 = f2;
  655. select f1, sum(f1) over (partition by f1 order by f2
  656. range between 1 preceding and 1 following)
  657. from t1 where f1 = f2;
  658. select f1, sum(f1) over (partition by f1, f1 order by f2
  659. range between 2 preceding and 1 preceding)
  660. from t1 where f1 = f2;
  661. select f1, sum(f1) over (partition by f1, f2 order by f2
  662. range between 1 following and 2 following)
  663. from t1 where f1 = f2;
  664. select f1, sum(f1) over (partition by f1
  665. groups between 1 preceding and 1 following)
  666. from t1 where f1 = f2; -- error, must have order by
  667. explain (costs off)
  668. select f1, sum(f1) over (partition by f1 order by f2
  669. groups between 1 preceding and 1 following)
  670. from t1 where f1 = f2;
  671. select f1, sum(f1) over (partition by f1 order by f2
  672. groups between 1 preceding and 1 following)
  673. from t1 where f1 = f2;
  674. select f1, sum(f1) over (partition by f1, f1 order by f2
  675. groups between 2 preceding and 1 preceding)
  676. from t1 where f1 = f2;
  677. select f1, sum(f1) over (partition by f1, f2 order by f2
  678. groups between 1 following and 2 following)
  679. from t1 where f1 = f2;
  680. -- ordering by a non-integer constant is allowed
  681. SELECT rank() OVER (ORDER BY length('abc'));
  682. -- can't order by another window function
  683. SELECT rank() OVER (ORDER BY rank() OVER (ORDER BY random()));
  684. -- some other errors
  685. SELECT * FROM empsalary WHERE row_number() OVER (ORDER BY salary) < 10;
  686. SELECT * FROM empsalary INNER JOIN tenk1 ON row_number() OVER (ORDER BY salary) < 10;
  687. SELECT rank() OVER (ORDER BY 1), count(*) FROM empsalary GROUP BY 1;
  688. SELECT * FROM rank() OVER (ORDER BY random());
  689. DELETE FROM empsalary WHERE (rank() OVER (ORDER BY random())) > 10;
  690. DELETE FROM empsalary RETURNING rank() OVER (ORDER BY random());
  691. SELECT count(*) OVER w FROM tenk1 WINDOW w AS (ORDER BY unique1), w AS (ORDER BY unique1);
  692. SELECT rank() OVER (PARTITION BY four, ORDER BY ten) FROM tenk1;
  693. SELECT count() OVER () FROM tenk1;
  694. SELECT generate_series(1, 100) OVER () FROM empsalary;
  695. SELECT ntile(0) OVER (ORDER BY ten), ten, four FROM tenk1;
  696. SELECT nth_value(four, 0) OVER (ORDER BY ten), ten, four FROM tenk1;
  697. -- filter
  698. SELECT sum(salary), row_number() OVER (ORDER BY depname), sum(
  699. sum(salary) FILTER (WHERE enroll_date > '2007-01-01')
  700. ) FILTER (WHERE depname <> 'sales') OVER (ORDER BY depname DESC) AS "filtered_sum",
  701. depname
  702. FROM empsalary GROUP BY depname;
  703. -- Test pushdown of quals into a subquery containing window functions
  704. -- pushdown is safe because all PARTITION BY clauses include depname:
  705. EXPLAIN (COSTS OFF)
  706. SELECT * FROM
  707. (SELECT depname,
  708. sum(salary) OVER (PARTITION BY depname) depsalary,
  709. min(salary) OVER (PARTITION BY depname || 'A', depname) depminsalary
  710. FROM empsalary) emp
  711. WHERE depname = 'sales';
  712. -- pushdown is unsafe because there's a PARTITION BY clause without depname:
  713. EXPLAIN (COSTS OFF)
  714. SELECT * FROM
  715. (SELECT depname,
  716. sum(salary) OVER (PARTITION BY enroll_date) enroll_salary,
  717. min(salary) OVER (PARTITION BY depname) depminsalary
  718. FROM empsalary) emp
  719. WHERE depname = 'sales';
  720. -- Test Sort node collapsing
  721. EXPLAIN (COSTS OFF)
  722. SELECT * FROM
  723. (SELECT depname,
  724. sum(salary) OVER (PARTITION BY depname order by empno) depsalary,
  725. min(salary) OVER (PARTITION BY depname, empno order by enroll_date) depminsalary
  726. FROM empsalary) emp
  727. WHERE depname = 'sales';
  728. -- Test Sort node reordering
  729. EXPLAIN (COSTS OFF)
  730. SELECT
  731. lead(1) OVER (PARTITION BY depname ORDER BY salary, enroll_date),
  732. lag(1) OVER (PARTITION BY depname ORDER BY salary,enroll_date,empno)
  733. FROM empsalary;
  734. -- Test incremental sorting
  735. EXPLAIN (COSTS OFF)
  736. SELECT * FROM
  737. (SELECT depname,
  738. empno,
  739. salary,
  740. enroll_date,
  741. row_number() OVER (PARTITION BY depname ORDER BY enroll_date) AS first_emp,
  742. row_number() OVER (PARTITION BY depname ORDER BY enroll_date DESC) AS last_emp
  743. FROM empsalary) emp
  744. WHERE first_emp = 1 OR last_emp = 1;
  745. SELECT * FROM
  746. (SELECT depname,
  747. empno,
  748. salary,
  749. enroll_date,
  750. row_number() OVER (PARTITION BY depname ORDER BY enroll_date) AS first_emp,
  751. row_number() OVER (PARTITION BY depname ORDER BY enroll_date DESC) AS last_emp
  752. FROM empsalary) emp
  753. WHERE first_emp = 1 OR last_emp = 1;
  754. -- cleanup
  755. DROP TABLE empsalary;
  756. -- test user-defined window function with named args and default args
  757. CREATE FUNCTION nth_value_def(val anyelement, n integer = 1) RETURNS anyelement
  758. LANGUAGE internal WINDOW IMMUTABLE STRICT AS 'window_nth_value';
  759. SELECT nth_value_def(n := 2, val := ten) OVER (PARTITION BY four), ten, four
  760. FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten) s;
  761. SELECT nth_value_def(ten) OVER (PARTITION BY four), ten, four
  762. FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten) s;
  763. --
  764. -- Test the basic moving-aggregate machinery
  765. --
  766. -- create aggregates that record the series of transform calls (these are
  767. -- intentionally not true inverses)
  768. CREATE FUNCTION logging_sfunc_nonstrict(text, anyelement) RETURNS text AS
  769. $$ SELECT COALESCE($1, '') || '*' || quote_nullable($2) $$
  770. LANGUAGE SQL IMMUTABLE;
  771. CREATE FUNCTION logging_msfunc_nonstrict(text, anyelement) RETURNS text AS
  772. $$ SELECT COALESCE($1, '') || '+' || quote_nullable($2) $$
  773. LANGUAGE SQL IMMUTABLE;
  774. CREATE FUNCTION logging_minvfunc_nonstrict(text, anyelement) RETURNS text AS
  775. $$ SELECT $1 || '-' || quote_nullable($2) $$
  776. LANGUAGE SQL IMMUTABLE;
  777. CREATE AGGREGATE logging_agg_nonstrict (anyelement)
  778. (
  779. stype = text,
  780. sfunc = logging_sfunc_nonstrict,
  781. mstype = text,
  782. msfunc = logging_msfunc_nonstrict,
  783. minvfunc = logging_minvfunc_nonstrict
  784. );
  785. CREATE AGGREGATE logging_agg_nonstrict_initcond (anyelement)
  786. (
  787. stype = text,
  788. sfunc = logging_sfunc_nonstrict,
  789. mstype = text,
  790. msfunc = logging_msfunc_nonstrict,
  791. minvfunc = logging_minvfunc_nonstrict,
  792. initcond = 'I',
  793. minitcond = 'MI'
  794. );
  795. CREATE FUNCTION logging_sfunc_strict(text, anyelement) RETURNS text AS
  796. $$ SELECT $1 || '*' || quote_nullable($2) $$
  797. LANGUAGE SQL STRICT IMMUTABLE;
  798. CREATE FUNCTION logging_msfunc_strict(text, anyelement) RETURNS text AS
  799. $$ SELECT $1 || '+' || quote_nullable($2) $$
  800. LANGUAGE SQL STRICT IMMUTABLE;
  801. CREATE FUNCTION logging_minvfunc_strict(text, anyelement) RETURNS text AS
  802. $$ SELECT $1 || '-' || quote_nullable($2) $$
  803. LANGUAGE SQL STRICT IMMUTABLE;
  804. CREATE AGGREGATE logging_agg_strict (text)
  805. (
  806. stype = text,
  807. sfunc = logging_sfunc_strict,
  808. mstype = text,
  809. msfunc = logging_msfunc_strict,
  810. minvfunc = logging_minvfunc_strict
  811. );
  812. CREATE AGGREGATE logging_agg_strict_initcond (anyelement)
  813. (
  814. stype = text,
  815. sfunc = logging_sfunc_strict,
  816. mstype = text,
  817. msfunc = logging_msfunc_strict,
  818. minvfunc = logging_minvfunc_strict,
  819. initcond = 'I',
  820. minitcond = 'MI'
  821. );
  822. -- test strict and non-strict cases
  823. SELECT
  824. p::text || ',' || i::text || ':' || COALESCE(v::text, 'NULL') AS row,
  825. logging_agg_nonstrict(v) over wnd as nstrict,
  826. logging_agg_nonstrict_initcond(v) over wnd as nstrict_init,
  827. logging_agg_strict(v::text) over wnd as strict,
  828. logging_agg_strict_initcond(v) over wnd as strict_init
  829. FROM (VALUES
  830. (1, 1, NULL),
  831. (1, 2, 'a'),
  832. (1, 3, 'b'),
  833. (1, 4, NULL),
  834. (1, 5, NULL),
  835. (1, 6, 'c'),
  836. (2, 1, NULL),
  837. (2, 2, 'x'),
  838. (3, 1, 'z')
  839. ) AS t(p, i, v)
  840. WINDOW wnd AS (PARTITION BY P ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
  841. ORDER BY p, i;
  842. -- and again, but with filter
  843. SELECT
  844. p::text || ',' || i::text || ':' ||
  845. CASE WHEN f THEN COALESCE(v::text, 'NULL') ELSE '-' END as row,
  846. logging_agg_nonstrict(v) filter(where f) over wnd as nstrict_filt,
  847. logging_agg_nonstrict_initcond(v) filter(where f) over wnd as nstrict_init_filt,
  848. logging_agg_strict(v::text) filter(where f) over wnd as strict_filt,
  849. logging_agg_strict_initcond(v) filter(where f) over wnd as strict_init_filt
  850. FROM (VALUES
  851. (1, 1, true, NULL),
  852. (1, 2, false, 'a'),
  853. (1, 3, true, 'b'),
  854. (1, 4, false, NULL),
  855. (1, 5, false, NULL),
  856. (1, 6, false, 'c'),
  857. (2, 1, false, NULL),
  858. (2, 2, true, 'x'),
  859. (3, 1, true, 'z')
  860. ) AS t(p, i, f, v)
  861. WINDOW wnd AS (PARTITION BY p ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
  862. ORDER BY p, i;
  863. -- test that volatile arguments disable moving-aggregate mode
  864. SELECT
  865. i::text || ':' || COALESCE(v::text, 'NULL') as row,
  866. logging_agg_strict(v::text)
  867. over wnd as inverse,
  868. logging_agg_strict(v::text || CASE WHEN random() < 0 then '?' ELSE '' END)
  869. over wnd as noinverse
  870. FROM (VALUES
  871. (1, 'a'),
  872. (2, 'b'),
  873. (3, 'c')
  874. ) AS t(i, v)
  875. WINDOW wnd AS (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
  876. ORDER BY i;
  877. SELECT
  878. i::text || ':' || COALESCE(v::text, 'NULL') as row,
  879. logging_agg_strict(v::text) filter(where true)
  880. over wnd as inverse,
  881. logging_agg_strict(v::text) filter(where random() >= 0)
  882. over wnd as noinverse
  883. FROM (VALUES
  884. (1, 'a'),
  885. (2, 'b'),
  886. (3, 'c')
  887. ) AS t(i, v)
  888. WINDOW wnd AS (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
  889. ORDER BY i;
  890. -- test that non-overlapping windows don't use inverse transitions
  891. SELECT
  892. logging_agg_strict(v::text) OVER wnd
  893. FROM (VALUES
  894. (1, 'a'),
  895. (2, 'b'),
  896. (3, 'c')
  897. ) AS t(i, v)
  898. WINDOW wnd AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND CURRENT ROW)
  899. ORDER BY i;
  900. -- test that returning NULL from the inverse transition functions
  901. -- restarts the aggregation from scratch. The second aggregate is supposed
  902. -- to test cases where only some aggregates restart, the third one checks
  903. -- that one aggregate restarting doesn't cause others to restart.
  904. CREATE FUNCTION sum_int_randrestart_minvfunc(int4, int4) RETURNS int4 AS
  905. $$ SELECT CASE WHEN random() < 0.2 THEN NULL ELSE $1 - $2 END $$
  906. LANGUAGE SQL STRICT;
  907. CREATE AGGREGATE sum_int_randomrestart (int4)
  908. (
  909. stype = int4,
  910. sfunc = int4pl,
  911. mstype = int4,
  912. msfunc = int4pl,
  913. minvfunc = sum_int_randrestart_minvfunc
  914. );
  915. WITH
  916. vs AS (
  917. SELECT i, (random() * 100)::int4 AS v
  918. FROM generate_series(1, 100) AS i
  919. ),
  920. sum_following AS (
  921. SELECT i, SUM(v) OVER
  922. (ORDER BY i DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS s
  923. FROM vs
  924. )
  925. SELECT DISTINCT
  926. sum_following.s = sum_int_randomrestart(v) OVER fwd AS eq1,
  927. -sum_following.s = sum_int_randomrestart(-v) OVER fwd AS eq2,
  928. 100*3+(vs.i-1)*3 = length(logging_agg_nonstrict(''::text) OVER fwd) AS eq3
  929. FROM vs
  930. JOIN sum_following ON sum_following.i = vs.i
  931. WINDOW fwd AS (
  932. ORDER BY vs.i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  933. );
  934. --
  935. -- Test various built-in aggregates that have moving-aggregate support
  936. --
  937. -- test inverse transition functions handle NULLs properly
  938. SELECT i,AVG(v::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  939. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  940. SELECT i,AVG(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  941. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  942. SELECT i,AVG(v::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  943. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  944. SELECT i,AVG(v::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  945. FROM (VALUES(1,1.5),(2,2.5),(3,NULL),(4,NULL)) t(i,v);
  946. SELECT i,AVG(v::interval) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  947. FROM (VALUES(1,'1 sec'),(2,'2 sec'),(3,NULL),(4,NULL)) t(i,v);
  948. SELECT i,SUM(v::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  949. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  950. SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  951. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  952. SELECT i,SUM(v::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  953. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  954. SELECT i,SUM(v::money) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  955. FROM (VALUES(1,'1.10'),(2,'2.20'),(3,NULL),(4,NULL)) t(i,v);
  956. SELECT i,SUM(v::interval) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  957. FROM (VALUES(1,'1 sec'),(2,'2 sec'),(3,NULL),(4,NULL)) t(i,v);
  958. SELECT i,SUM(v::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  959. FROM (VALUES(1,1.1),(2,2.2),(3,NULL),(4,NULL)) t(i,v);
  960. SELECT SUM(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  961. FROM (VALUES(1,1.01),(2,2),(3,3)) v(i,n);
  962. SELECT i,COUNT(v) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  963. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  964. SELECT i,COUNT(*) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  965. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  966. SELECT VAR_POP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  967. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  968. SELECT VAR_POP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  969. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  970. SELECT VAR_POP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  971. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  972. SELECT VAR_POP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  973. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  974. SELECT VAR_SAMP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  975. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  976. SELECT VAR_SAMP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  977. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  978. SELECT VAR_SAMP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  979. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  980. SELECT VAR_SAMP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  981. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  982. SELECT VARIANCE(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  983. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  984. SELECT VARIANCE(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  985. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  986. SELECT VARIANCE(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  987. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  988. SELECT VARIANCE(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  989. FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  990. SELECT STDDEV_POP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  991. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  992. SELECT STDDEV_POP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  993. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  994. SELECT STDDEV_POP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  995. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  996. SELECT STDDEV_POP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  997. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  998. SELECT STDDEV_SAMP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  999. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  1000. SELECT STDDEV_SAMP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  1001. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  1002. SELECT STDDEV_SAMP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  1003. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  1004. SELECT STDDEV_SAMP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  1005. FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n);
  1006. SELECT STDDEV(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  1007. FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  1008. SELECT STDDEV(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  1009. FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  1010. SELECT STDDEV(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  1011. FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  1012. SELECT STDDEV(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
  1013. FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n);
  1014. -- test that inverse transition functions work with various frame options
  1015. SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND CURRENT ROW)
  1016. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  1017. SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
  1018. FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v);
  1019. SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
  1020. FROM (VALUES(1,1),(2,2),(3,3),(4,4)) t(i,v);
  1021. -- ensure aggregate over numeric properly recovers from NaN values
  1022. SELECT a, b,
  1023. SUM(b) OVER(ORDER BY A ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
  1024. FROM (VALUES(1,1::numeric),(2,2),(3,'NaN'),(4,3),(5,4)) t(a,b);
  1025. -- It might be tempting for someone to add an inverse trans function for
  1026. -- float and double precision. This should not be done as it can give incorrect
  1027. -- results. This test should fail if anyone ever does this without thinking too
  1028. -- hard about it.
  1029. SELECT to_char(SUM(n::float8) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),'999999999999999999999D9')
  1030. FROM (VALUES(1,1e20),(2,1)) n(i,n);
  1031. SELECT i, b, bool_and(b) OVER w, bool_or(b) OVER w
  1032. FROM (VALUES (1,true), (2,true), (3,false), (4,false), (5,true)) v(i,b)
  1033. WINDOW w AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING);
  1034. -- Tests for problems with failure to walk or mutate expressions
  1035. -- within window frame clauses.
  1036. -- test walker (fails with collation error if expressions are not walked)
  1037. SELECT array_agg(i) OVER w
  1038. FROM generate_series(1,5) i
  1039. WINDOW w AS (ORDER BY i ROWS BETWEEN (('foo' < 'foobar')::integer) PRECEDING AND CURRENT ROW);
  1040. -- test mutator (fails when inlined if expressions are not mutated)
  1041. CREATE FUNCTION pg_temp.f(group_size BIGINT) RETURNS SETOF integer[]
  1042. AS $$
  1043. SELECT array_agg(s) OVER w
  1044. FROM generate_series(1,5) s
  1045. WINDOW w AS (ORDER BY s ROWS BETWEEN CURRENT ROW AND GROUP_SIZE FOLLOWING)
  1046. $$ LANGUAGE SQL STABLE;
  1047. EXPLAIN (costs off) SELECT * FROM pg_temp.f(2);
  1048. SELECT * FROM pg_temp.f(2);