PostgreSQL

Extensions

  • Horizontal Scaling and Sharding: Citus DB
  • Columnar Data Storage: cstore_fdw
  • Files as Tables: file_fdw
  • Streaming Computations: PipelineDB
  • Timeseries: TimescaleDB

Generate Series

create table product (
  id serial primary key,
  created_at DATE,
  price NUMERIC(4,2)
);

insert into product (created_at, price) VALUES (
  generate_series('2015-01-12', '2015-02-22', interval '1 day'),
  generate_series(2.33, 45.12, 1.05)
);

Update Case-When

update product set kind = (
  case kind
  when 'book' then 'book_kind'
  when 'cd'   then 'cd_kind'
  end
) where kind in ('book', 'cd');

Insert Multiple

insert into widget (name) values ('Widget 1'), ('Widget 2'), ('Widget 3');

UUID

create extension "uuid-ossp";

... = uuid_generate_v4();

Truncate

Truncate doesn't scan the entire table while DELETE FROM without WHERE does.

Group vs Non-Group

select create_date, name from widget where create_date = (select min(create_date) from widget);

This won't work:

select min(create_date), name from widget;

Functions

PostgreSQL allows to run pre-defined code via user-defined functions. Those functions can be written not only in SQL, but also in C, Python, Perl, Tcl or PL/pgSQL.

SQL Functions

SQL functions can accept and return base types, composite types and rows. They support variable numbers of arguments, default values for arguments and polymorphic arguments.

SQL functions can return multiple rows or nothing.

The function body can only contain SQL statements (no ifs/else, no variables, no loops).

C Functions

C functions can be built as a shared library that can be dynamically loaded.

PL/pgSQL Functions

PL/pgSQL is a full-fledged programming language with variables, expressions and control statements. In particular, it includes features like cursors to work with SQL data.

Python Functions

sudo apt install postgresql-plpython-11
CREATE EXTENSION plpythonu;

Aggregate Functions

Aggregate functions operate over a set of values, and return a single result.

User-defined aggregate function:

CREATE OR REPLACE FUNCTION _final_median(NUMERIC[])
   RETURNS NUMERIC AS
$$
   SELECT AVG(val)
   FROM (
     SELECT val
     FROM unnest($1) val
     ORDER BY 1
     LIMIT  2 - MOD(array_upper($1, 1), 2)
     OFFSET CEIL(array_upper($1, 1) / 2.0) - 1
   ) sub;
$$
LANGUAGE 'sql' IMMUTABLE;

CREATE AGGREGATE median(NUMERIC) (
  SFUNC=array_append,
  STYPE=NUMERIC[],
  FINALFUNC=_final_median,
  INITCOND='{}'
);