From 6066ed206b34d1c8aa7e63814e51b68674d221e1 Mon Sep 17 00:00:00 2001 From: Eunjae Lee Date: Wed, 10 Sep 2025 12:13:29 +0200 Subject: [PATCH] fix: Fix booking count discrepancy between KPI cards and trends chart (#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 * 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 * address feedback --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../service/InsightsBookingBaseService.ts | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/packages/lib/server/service/InsightsBookingBaseService.ts b/packages/lib/server/service/InsightsBookingBaseService.ts index 9877bff2a6..7e0f7f806c 100644 --- a/packages/lib/server/service/InsightsBookingBaseService.ts +++ b/packages/lib/server/service/InsightsBookingBaseService.ts @@ -650,31 +650,42 @@ export class InsightsBookingBaseService { noShowGuests: number; }[] >` - SELECT - "date", - CAST(COUNT(*) AS INTEGER) AS "bookingsCount", - CAST(COUNT(CASE WHEN "isNoShowGuest" = true THEN 1 END) AS INTEGER) AS "noShowGuests", - "timeStatus", - "noShowHost" - FROM ( + WITH booking_stats AS ( SELECT DATE("createdAt" AT TIME ZONE ${timeZone}) as "date", - "a"."noShow" AS "isNoShowGuest", "timeStatus", - "noShowHost" - FROM - "BookingTimeStatusDenormalized" - JOIN - "Attendee" "a" ON "a"."bookingId" = "BookingTimeStatusDenormalized"."id" - WHERE - ${baseConditions} - ) AS bookings - GROUP BY - "date", - "timeStatus", - "noShowHost" - ORDER BY - "date" + COALESCE("noShowHost", false) AS "noShowHost", + COUNT(*) as "bookingsCount" + FROM "BookingTimeStatusDenormalized" + WHERE ${baseConditions} + GROUP BY + 1, 2, 3 + ), + guest_stats AS ( + SELECT + DATE(b."createdAt" AT TIME ZONE ${timeZone}) as "date", + b."timeStatus", + COALESCE(b."noShowHost", false) AS "noShowHost", + COUNT(CASE WHEN a."noShow" = true THEN 1 END) as "noShowGuests" + FROM "BookingTimeStatusDenormalized" b + INNER JOIN "Attendee" a ON a."bookingId" = b.id + WHERE ${baseConditions} + GROUP BY + 1, 2, 3 + ) + SELECT + bs."date", + CAST(bs."bookingsCount" AS INTEGER) AS "bookingsCount", + bs."timeStatus", + bs."noShowHost", + CAST(COALESCE(gs."noShowGuests", 0) AS INTEGER) AS "noShowGuests" + FROM booking_stats bs + LEFT JOIN guest_stats gs ON ( + bs."date" = gs."date" AND + bs."timeStatus" = gs."timeStatus" AND + bs."noShowHost" = gs."noShowHost" + ) + ORDER BY bs."date" `; // Initialize aggregate object with zero counts for all date ranges