Referee
Both numbers are right. Here is what each one counts that the other doesn't. ✓ Adds up: 1'102 − 749 + 106 = 459, and both totals match the numbers on the overview. Every step comes from the two definitions: the date each one counts by, and what it filters out. Only counts can be compared this way; revenue adds up francs, not leads.
Leads (Marketing)
1'102
Appointments (Operations)
459
Marketing counts 643 more. 353 leads are in both.
Where the difference comes from
Counted by Marketing only
-
No appointment yet−429
Show 5 examples
Lead Created Appointment Status Invoiced 3541 01.09.2026 No appointment 3542 01.09.2026 No appointment 3544 01.09.2026 No appointment 3546 01.09.2026 No appointment 3548 01.09.2026 No appointment -
Appointment after September−220
Show 5 examples
Lead Created Appointment Status Invoiced 3771 07.09.2026 01.10.2026 Held 3839 09.09.2026 03.10.2026 Held 3850 09.09.2026 01.10.2026 Held 18.10.2026 3854 09.09.2026 01.10.2026 Held 3872 09.09.2026 01.10.2026 Held 20.10.2026 -
Cancelled or no-show−100
Show 5 examples
Lead Created Appointment Status Invoiced 3545 01.09.2026 25.09.2026 Cancelled 3553 01.09.2026 07.09.2026 Cancelled 3563 01.09.2026 04.09.2026 Cancelled 3564 01.09.2026 25.09.2026 No-show 3582 01.09.2026 02.09.2026 No-show
Counted by Operations only
-
Created before September+106
Show 5 examples
Lead Created Appointment Status Invoiced 3029 10.08.2026 03.09.2026 Held 3032 10.08.2026 01.09.2026 Held 10.09.2026 3063 11.08.2026 04.09.2026 Held 3068 11.08.2026 03.09.2026 Held 22.09.2026 3071 11.08.2026 03.09.2026 Held 16.09.2026
How it's calculated
Rows per step
with scoped as (
select lead_id, created_at, channel, canton, product, broker, appointment_at, appointment_status, contract_signed_at, invoiced_at, invoice_amount_chf,
coalesce((created_at >= timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' and created_at < timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich'), false) as in_a,
coalesce((appointment_at >= timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' and appointment_at < timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich'), false) and coalesce(appointment_status in ('scheduled', 'held'), false) as in_b
from leads
where (created_at >= timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' and created_at < timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich')
or (appointment_at >= timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' and appointment_at < timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich')
),
classified as (
select scoped.*,
case when in_a and not in_b then case when appointment_at is null then 'minus:time_null'
when appointment_at < timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' then 'minus:time_before'
when appointment_at >= timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich' then 'minus:time_after'
else 'minus:filter' end
when in_b and not in_a then case when created_at is null then 'plus:time_null'
when created_at < timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' then 'plus:time_before'
when created_at >= timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich' then 'plus:time_after'
else 'plus:filter' end
when in_a then 'both'
else 'neither' end as bucket
from scoped
),
stepped as (
select s.step, classified.*
from classified
cross join lateral (values (case when in_a then 'start' end),
(case when in_b then 'end' end),
(bucket)) as s(step)
where s.step is not null
)
select step, count(*) as n
from stepped
group by step
order by stepExamples per step
with scoped as (
select lead_id, created_at, channel, canton, product, broker, appointment_at, appointment_status, contract_signed_at, invoiced_at, invoice_amount_chf,
coalesce((created_at >= timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' and created_at < timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich'), false) as in_a,
coalesce((appointment_at >= timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' and appointment_at < timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich'), false) and coalesce(appointment_status in ('scheduled', 'held'), false) as in_b
from leads
where (created_at >= timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' and created_at < timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich')
or (appointment_at >= timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' and appointment_at < timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich')
),
classified as (
select scoped.*,
case when in_a and not in_b then case when appointment_at is null then 'minus:time_null'
when appointment_at < timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' then 'minus:time_before'
when appointment_at >= timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich' then 'minus:time_after'
else 'minus:filter' end
when in_b and not in_a then case when created_at is null then 'plus:time_null'
when created_at < timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich' then 'plus:time_before'
when created_at >= timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich' then 'plus:time_after'
else 'plus:filter' end
when in_a then 'both'
else 'neither' end as bucket
from scoped
),
stepped as (
select s.step, classified.*
from classified
cross join lateral (values (case when in_a then 'start' end),
(case when in_b then 'end' end),
(bucket)) as s(step)
where s.step is not null
)
select step, lead_id, created_at, channel, canton, product, broker, appointment_at, appointment_status, contract_signed_at, invoiced_at, invoice_amount_chf
from (
select stepped.*, row_number() over (partition by step order by lead_id) as rn
from stepped
where step not in ('both', 'neither')
) ranked
where rn <= 5
order by step, lead_idLeads (Marketing)
select count(distinct lead_id) as value
from leads
where created_at >= timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich'
and created_at < timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich'Appointments (Operations)
select count(distinct lead_id) as value
from leads
where appointment_at >= timestamp '2026-09-01 00:00:00' at time zone 'Europe/Zurich'
and appointment_at < timestamp '2026-10-01 00:00:00' at time zone 'Europe/Zurich'
and appointment_status in ('scheduled', 'held')
The app runs these queries with parameters; here the values are written in, so they can be read or pasted into psql.