runtime
20 / 88

lesson 20 Joins & sets · intermediate

Ratios, ROUND & NULLIF

Calculate safe ratios and round your results.

the idea

A ratio needs a defined numerator and denominator. Multiply by 100.0 before dividing so SQLite does not use integer division, ROUND the result for display, and wrap the denominator in NULLIF(…, 0) so an empty group gives NULL instead of a misleading number.

Dataset: Product / SaaS Analytics

The tables the challenges use, with their first 6 rows. Under each column name: the kind of value it holds, and which table it links to.

invitations7 columns · 6,450 rows
invitation_idnumber · unique idaccount_idnumber · links to accountsinvited_by_user_idnumber · links to usersinvitee_emailtextsent_atdate & timeaccepted_atdate & timeaccepted_user_idnumber · links to users
111deepa.bell@ironcapital1.example2024-01-21 11:24:152024-01-24 03:43:142
211sofia.wilson@mail.example2024-02-02 07:45:532024-02-02 21:34:253
326nadia.flores@vectordata2.example2024-01-25 09:18:58NULLNULL
426rosa.jones@vectordata2.example2024-02-03 06:27:242024-02-03 07:03:467
5310raj.li@truefoods3.example2024-01-20 15:16:56NULLNULL
6310ayesha.silva@truefoods3.example2024-01-24 19:32:042024-01-26 05:58:0311
invitation_idnumber · unique id
1
account_idnumber · links to accounts
1
invited_by_user_idnumber · links to users
1
invitee_emailtext
deepa.bell@ironcapital1.example
sent_atdate & time
2024-01-21 11:24:15
accepted_atdate & time
2024-01-24 03:43:14
accepted_user_idnumber · links to users
2
invitation_idnumber · unique id
2
account_idnumber · links to accounts
1
invited_by_user_idnumber · links to users
1
invitee_emailtext
sofia.wilson@mail.example
sent_atdate & time
2024-02-02 07:45:53
accepted_atdate & time
2024-02-02 21:34:25
accepted_user_idnumber · links to users
3
invitation_idnumber · unique id
3
account_idnumber · links to accounts
2
invited_by_user_idnumber · links to users
6
invitee_emailtext
nadia.flores@vectordata2.example
sent_atdate & time
2024-01-25 09:18:58
accepted_atdate & time
NULL
accepted_user_idnumber · links to users
NULL
invitation_idnumber · unique id
4
account_idnumber · links to accounts
2
invited_by_user_idnumber · links to users
6
invitee_emailtext
rosa.jones@vectordata2.example
sent_atdate & time
2024-02-03 06:27:24
accepted_atdate & time
2024-02-03 07:03:46
accepted_user_idnumber · links to users
7
invitation_idnumber · unique id
5
account_idnumber · links to accounts
3
invited_by_user_idnumber · links to users
10
invitee_emailtext
raj.li@truefoods3.example
sent_atdate & time
2024-01-20 15:16:56
accepted_atdate & time
NULL
accepted_user_idnumber · links to users
NULL
invitation_idnumber · unique id
6
account_idnumber · links to accounts
3
invited_by_user_idnumber · links to users
10
invitee_emailtext
ayesha.silva@truefoods3.example
sent_atdate & time
2024-01-24 19:32:04
accepted_atdate & time
2024-01-26 05:58:03
accepted_user_idnumber · links to users
11

first 6 of 6,450 rows · your queries use all of them

accounts7 columns · 3,200 rows
account_idnumber · unique idaccount_nametextindustrytextcompany_sizetextcountrytextacquisition_channeltextcreated_atdate & time
1Iron Capital IncLogistics11-50United Statesorganic2024-01-14 18:52:14
2Vector Data CoNonprofit51-200United Kingdomsocial2024-01-15 13:21:52
3True Foods IncHealthcare201-1000United Statesoutbound_sales2024-01-19 11:22:02
4Meridian WorksSoftware11-50United Statesorganic2024-01-23 23:42:36
5Prism Health GroupSoftware1-10Germanyreferral2024-01-25 11:43:43
6Beacon Supply LtdMedia1000+United Kingdomorganic2024-01-27 20:19:28
account_idnumber · unique id
1
account_nametext
Iron Capital Inc
industrytext
Logistics
company_sizetext
11-50
countrytext
United States
acquisition_channeltext
organic
created_atdate & time
2024-01-14 18:52:14
account_idnumber · unique id
2
account_nametext
Vector Data Co
industrytext
Nonprofit
company_sizetext
51-200
countrytext
United Kingdom
acquisition_channeltext
social
created_atdate & time
2024-01-15 13:21:52
account_idnumber · unique id
3
account_nametext
True Foods Inc
industrytext
Healthcare
company_sizetext
201-1000
countrytext
United States
acquisition_channeltext
outbound_sales
created_atdate & time
2024-01-19 11:22:02
account_idnumber · unique id
4
account_nametext
Meridian Works
industrytext
Software
company_sizetext
11-50
countrytext
United States
acquisition_channeltext
organic
created_atdate & time
2024-01-23 23:42:36
account_idnumber · unique id
5
account_nametext
Prism Health Group
industrytext
Software
company_sizetext
1-10
countrytext
Germany
acquisition_channeltext
referral
created_atdate & time
2024-01-25 11:43:43
account_idnumber · unique id
6
account_nametext
Beacon Supply Ltd
industrytext
Media
company_sizetext
1000+
countrytext
United Kingdom
acquisition_channeltext
organic
created_atdate & time
2024-01-27 20:19:28

first 6 of 3,200 rows · your queries use all of them

worked example

Run these steps in order to see the idea before you write your own query. The step marked “the pattern” is what the challenges ask for. Running the example does not count toward progress.

  1. Count sent and accepted per workspace. Run this. COUNT(*) is invitations sent; COUNT(accepted_at) counts those with an acceptance timestamp.

    step-1.sql
    SELECT account_id, COUNT(*) AS sent, COUNT(accepted_at) AS accepted
    FROM invitations
    GROUP BY account_id
    LIMIT 15;
  2. Divide without breaking on zero. Run this. NULLIF turns a zero denominator into NULL so you do not divide by zero; 100.0 avoids integer division.

    step-2.sql
    SELECT
      100.0 * 3 / NULLIF(0, 0) AS undefined_rate,
      ROUND(100.0 * 3 / 7, 2) AS rate;
  3. Put it together. The lesson's pattern in one query.the pattern

    example.sql
    SELECT account_id, COUNT(*) AS sent, COUNT(accepted_at) AS accepted
    FROM invitations
    GROUP BY account_id;

common mistake

COUNT(accepted_at) / COUNT(*) is integer division in SQLite and returns 0 for most accounts.

challenge 1

For every workspace that sent invitations, return account_id, invitations_sent, accepted and acceptance_pct (0–100, rounded to 2 decimals).

what to return

Columns
account_idinvitations_sentacceptedacceptance_pct in this order
Rows
any order
challenge-1.sql
 
To master this lesson, solve both challenges without hints and pass the concept check. 3 of 3 to go.
Ratios, ROUND & NULLIF — Joins & sets · Runtime