On Github keithf4 / dont_forget_the_elephant
Presented by Keith Fiske / @keithf4
Database Administrator @ OmniTI
Follow along at http://slides.keithf4.com/dontforget
SELECT salary, sum(salary) OVER () FROM empsalary; salary | sum --------+------- 5200 | 47100 5000 | 47100 3500 | 47100 4800 | 47100 3900 | 47100 4200 | 47100 4500 | 47100 4800 | 47100 6000 | 47100 5200 | 47100 (10 rows) SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary; salary | sum --------+------- 3500 | 3500 3900 | 7400 4200 | 11600 4500 | 16100 4800 | 25700 4800 | 25700 5000 | 30700 5200 | 41100 5200 | 41100 6000 | 47100 (10 rows)
SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary; depname | empno | salary | avg -----------+-------+--------+----------------------- develop | 11 | 5200 | 5020.0000000000000000 develop | 7 | 4200 | 5020.0000000000000000 develop | 9 | 4500 | 5020.0000000000000000 develop | 8 | 6000 | 5020.0000000000000000 develop | 10 | 5200 | 5020.0000000000000000 personnel | 5 | 3500 | 3700.0000000000000000 personnel | 2 | 3900 | 3700.0000000000000000 sales | 3 | 4800 | 4866.6666666666666667 sales | 1 | 5000 | 4866.6666666666666667 sales | 4 | 4800 | 4866.6666666666666667 (10 rows) SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary DESC) FROM empsalary; depname | empno | salary | rank -----------+-------+--------+------ develop | 8 | 6000 | 1 develop | 10 | 5200 | 2 develop | 11 | 5200 | 2 develop | 9 | 4500 | 4 develop | 7 | 4200 | 5 personnel | 2 | 3900 | 1 personnel | 5 | 3500 | 2 sales | 1 | 5000 | 1 sales | 4 | 4800 | 2 sales | 3 | 4800 | 2 (10 rows)
WITH regional_sales AS ( SELECT region, SUM(amount) AS total_sales FROM orders GROUP BY region ), top_regions AS ( SELECT region FROM regional_sales WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales) ) SELECT region, product, SUM(quantity) AS product_units, SUM(amount) AS product_sales FROM orders WHERE region IN (SELECT region FROM top_regions) GROUP BY region, product;
WITH RECURSIVE t(n) AS ( VALUES (1) UNION ALL SELECT n+1 FROM t WHERE n < 100 ) SELECT sum(n) FROM t; sum ------ 5050 (1 row)Like a normal recursive function, there is an initial condition (VALUES(1)) followed by step to perform that refers back to itself. In this case the WHERE condition provides the exit from recursion.
WITH moved_rows AS ( DELETE FROM products WHERE "date" >= '2010-10-01' AND "date" < '2010-11-01' RETURNING * ) INSERT INTO products_log SELECT * FROM moved_rows;Rows deleted in WITH statement are returned by RETURNING to be used by the SELECT statement to populate another table that tracks deletes
BEFORE: BEGIN; INSERT INTO users (name, email) VALUES (?,?) RETURNING userid; INSERT INTO addresses (userid, address, city, state, zip) VALUES (?,?,?,?,?) RETURNING addressid; INSERT INTO user_history (userid, addressid, action) VALUES (?,?,?) RETURNING historyid; COMMIT; AFTER: WITH userdata AS ( INSERT INTO users (name, email) VALUES (?,?) RETURNING userid ), addressdata AS ( INSERT INTO addresses (userid, address, city, state, zip) SELECT userid,?,?,?,? FROM userdata RETURNING addressid ), historydata AS ( INSERT INTO user_history (userid, addressid, action) SELECT userid, addressid,? FROM userdata, addressdata RETURNING historyid ) SELECT userid, addressid, history id FROM userdata, addressdata, historydata;
-- includes 3, does not include 7, and does include all points in between SELECT '[3,7)'::int4range; -- does not include either 3 or 7, but includes all points in between SELECT '(3,7)'::int4range; -- includes only the single point 4 SELECT '[4,4]'::int4range; -- includes no points (and will be normalized to 'empty') SELECT '[4,4)'::int4range; CREATE TABLE reservation (room int, during tsrange); INSERT INTO reservation VALUES (1108, '[2010-01-01 14:30, 2010-01-01 15:30)'); -- Containment SELECT int4range(10, 20) @> 3; ?column? ---------- f -- Overlaps SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0); ?column? ---------- t -- Extract the upper bound SELECT upper(int8range(15, 25)); upper ------- 25 -- Compute the intersection SELECT int4range(10, 20) * int4range(15, 25); ?column? ---------- [15,20)
test=# SELECT * FROM cars ORDER BY lower(cars.price_range); id | name | price_range -----+---------------------+----------------- 2 | Buick Skylark | [2000,4001) 3 | Pontiac GTO | [5000,7501) 4 | Chevrolet Camero | [10000,12001) 5 | Ford Mustang | [11000,15001) 6 | Lincoln Continental | [12000,14001) 7 | BMW M3 | [35000,42001) 8 | Audi RS4 | [41000,45001) 9 | Porsche 911 | [47000,58001) 10 | Lamborghini LP700 | [385000,400001)
SELECT * FROM cars WHERE ( cars.min_price ≤ 13000 AND cars.min_price ≤ 15000 AND cars.max_price ≥ 13000 AND cars.max_price ≤ 15000 ) OR ( cars.min_price ≤ 13000 AND cars.min_price ≤ 15000 AND cars.max_price ≥ 13000 AND cars.max_price ≥ 15000 ) OR ( cars.min_price ≥ 13000 AND cars.min_price ≤ 15000 AND cars.max_price ≥ 13000 AND cars.max_price ≤ 15000 ) OR ( cars.min_price ≥ 13000 AND cars.min_price ≤ 15000 AND cars.max_price ≥ 13000 AND cars.max_price ≥ 15000 ) ORDER BY cars.min_price;
SELECT * FROM cars WHERE cars.price_range && int4range(13000, 15000, '[]') ORDER BY lower(cars.price_range); id | name | price_range ----+---------------------+--------------- 5 | Ford Mustang | [11000,15001) 6 | Lincoln Continental | [12000,14001)
IpcMemoryCreate: shmget(key=5432001, size=415776768, 03600) failed: Invalid argument This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently 415776768 bytes), reduce PostgreSQL's shared_buffers parameter (currently 50000) and/or its max_connections parameter (currently 12).