db.l3.ai

A share needs a numerator and a denominator

Counting is rarely the goal. The question is usually a proportion: out of all members, how many? out of all bookings, how many brought guests?

Write the two parts down first.

  • Numerator: bookings with at least one guest.
  • Denominator: all bookings.

Both come from the whole table, so both are aggregates. One query can compute them side by side:

SELECT
  count(CASE WHEN guests > 0 THEN 1 END) AS with_guests,
  count(*) AS total
FROM bookings;

Integer division

In Postgres 7 / 2 is 3, because both sides are integers. Cast one side to numeric to get a fraction, then round:

SELECT round(100.0 * count(CASE WHEN guests > 0 THEN 1 END) / count(*), 1) AS percent_with_guests
FROM bookings;

Multiplying by 100.0 first turns the whole expression into numeric.

Practice: Share of bookings with guests.

A strange query

If you select a bare column next to an aggregate, as in SELECT surname, count(*) FROM members, there is no single surname to show. Postgres rejects the query. Some other databases quietly pick a row, which hides the mistake.

This page is adapted from selectstarsql.com innocence.md (Zi Chong Kao, github.com/zichongkao/selectstarsql), changed. It is licensed under CC BY-SA 4.0 as a whole; share it under the same license. License text