Skip to content

Commit 6066ed2

Browse files
fix: Fix booking count discrepancy between KPI cards and trends chart (calcom#23619)
* fix: correct booking count in EventTrendsChart by restructuring SQL query - Replace JOIN-based query with CTE approach to count distinct bookings - Separate booking stats from guest stats to prevent duplicate counting - Preserve no-show guest functionality with LEFT JOIN - Ensure EventTrendsChart 'Created' sum matches BookingKPICards 'events_created' Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: use positional GROUP BY references to resolve PostgreSQL error - Replace column expressions in GROUP BY with positional references (1, 2, 3) - Fixes PostgreSQL error 42803 caused by parameter resolution in CTE queries - Maintains the same query logic while avoiding column reference conflicts Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * address feedback --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent d30d279 commit 6066ed2

1 file changed

Lines changed: 33 additions & 22 deletions

File tree

packages/lib/server/service/InsightsBookingBaseService.ts

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -650,31 +650,42 @@ export class InsightsBookingBaseService {
650650
noShowGuests: number;
651651
}[]
652652
>`
653-
SELECT
654-
"date",
655-
CAST(COUNT(*) AS INTEGER) AS "bookingsCount",
656-
CAST(COUNT(CASE WHEN "isNoShowGuest" = true THEN 1 END) AS INTEGER) AS "noShowGuests",
657-
"timeStatus",
658-
"noShowHost"
659-
FROM (
653+
WITH booking_stats AS (
660654
SELECT
661655
DATE("createdAt" AT TIME ZONE ${timeZone}) as "date",
662-
"a"."noShow" AS "isNoShowGuest",
663656
"timeStatus",
664-
"noShowHost"
665-
FROM
666-
"BookingTimeStatusDenormalized"
667-
JOIN
668-
"Attendee" "a" ON "a"."bookingId" = "BookingTimeStatusDenormalized"."id"
669-
WHERE
670-
${baseConditions}
671-
) AS bookings
672-
GROUP BY
673-
"date",
674-
"timeStatus",
675-
"noShowHost"
676-
ORDER BY
677-
"date"
657+
COALESCE("noShowHost", false) AS "noShowHost",
658+
COUNT(*) as "bookingsCount"
659+
FROM "BookingTimeStatusDenormalized"
660+
WHERE ${baseConditions}
661+
GROUP BY
662+
1, 2, 3
663+
),
664+
guest_stats AS (
665+
SELECT
666+
DATE(b."createdAt" AT TIME ZONE ${timeZone}) as "date",
667+
b."timeStatus",
668+
COALESCE(b."noShowHost", false) AS "noShowHost",
669+
COUNT(CASE WHEN a."noShow" = true THEN 1 END) as "noShowGuests"
670+
FROM "BookingTimeStatusDenormalized" b
671+
INNER JOIN "Attendee" a ON a."bookingId" = b.id
672+
WHERE ${baseConditions}
673+
GROUP BY
674+
1, 2, 3
675+
)
676+
SELECT
677+
bs."date",
678+
CAST(bs."bookingsCount" AS INTEGER) AS "bookingsCount",
679+
bs."timeStatus",
680+
bs."noShowHost",
681+
CAST(COALESCE(gs."noShowGuests", 0) AS INTEGER) AS "noShowGuests"
682+
FROM booking_stats bs
683+
LEFT JOIN guest_stats gs ON (
684+
bs."date" = gs."date" AND
685+
bs."timeStatus" = gs."timeStatus" AND
686+
bs."noShowHost" = gs."noShowHost"
687+
)
688+
ORDER BY bs."date"
678689
`;
679690

680691
// Initialize aggregate object with zero counts for all date ranges

0 commit comments

Comments
 (0)