Skip to main content

Planning Center Registrations SQL Queries

Query Planning Center Registrations data with SQL to track event signups, manage waitlists, and analyze attendance patterns across church events.

Manage Events and Track Signups with Data

Transform your event management with direct SQL access to Planning Center Registrations data. Track signups, manage waitlists, analyze attendance patterns, and ensure smooth event operations through powerful data insights.

Registrations relationship types come in two casings. Planning Center changed the casing of the Registrations relationship keys, and Parable kept both forms in the synced data: rows created before the change carry snake_case values (signup, registration, selection_type, person, emergency_contact), while newer rows carry PascalCase (Signup, Registration, SelectionType, Person, EmergencyContact).

Matching only one form silently drops roughly a third of your rows, so every example on these pages matches both:

AND ar.relationship_type IN ('Registration', 'registration')

This applies only to the Registrations module. Every other Planning Center module uses a single, consistent casing.

Quick Start

Ready to explore your registrations data? Here's your first query to see active signups:

-- See your 10 most recent event signups
SELECT 
    s.signup_id,
    s.name as event_name,
    s.description,
    s.open_at,
    s.close_at,
    COUNT(DISTINCT a.attendee_id) as attendee_count,
    COUNT(CASE WHEN a.waitlisted = true THEN 1 END) as waitlist_count
FROM planning_center.registrations_signups s
LEFT JOIN planning_center.registrations_attendees a 
    ON EXISTS (
        SELECT 1
        FROM planning_center.registrations_attendees_relationships ar
        JOIN planning_center.registrations_registrations_relationships rr
            ON rr.registration_id = ar.relationship_id
            AND rr.relationship_type IN ('Signup', 'signup')
        WHERE ar.attendee_id = a.attendee_id
        AND ar.relationship_type IN ('Registration', 'registration')
        AND rr.relationship_id = s.signup_id
    )
WHERE s.archived = false
GROUP BY s.signup_id, s.name, s.description, s.open_at, s.close_at, s.created_at
ORDER BY s.created_at DESC
LIMIT 10;

What You Can Do With Registrations Queries

📋 Event Management

  • Track registration counts and capacity
  • Monitor waitlist status and conversions
  • Analyze signup patterns and trends
  • Identify popular events and time slots

👥 Attendee Insights

  • Understand attendee demographics
  • Track repeat attendees across events
  • Analyze cancellation patterns
  • Monitor emergency contact completeness

📍 Location Analytics

  • Analyze event locations and venues
  • Track geographic distribution of attendees
  • Optimize location selection
  • Plan transportation and logistics

💰 Financial Tracking

  • Monitor registration fees and pricing tiers
  • Track payment collection status
  • Analyze discount usage
  • Report on event revenue

Available Tables

Your Planning Center Registrations data is organized into these primary tables:

TableWhat It ContainsKey Use Cases
registrations_signupsEvent signup formsEvent details, dates, capacity, archives
registrations_attendeesIndividual attendee recordsRegistration status, waitlist tracking
registrations_registrationsRegistration submissionsTracking individual registrations
registrations_categoriesEvent categoriesGrouping and filtering events
registrations_selection_typesPricing tiers and optionsSelection names, listed prices, availability
registrations_signup_locationsEvent venues with coordinatesLocation details, mapping, directions
registrations_signup_timesEvent date/time slotsSchedule management, calendar views
registrations_emergency_contactsEmergency contact informationSafety protocols, contact lists
registrations_peopleBasic person dataAttendee names and identification
registrations_campusesChurch campus locationsMulti-site event management
registrations_organizationsOrganization settingsAccount configuration

Understanding Relationships

Parable stores Planning Center relationships in separate tables to maintain data integrity. Key relationship patterns include:

  • registrations_signups_relationships - Links signups to categories, campuses, locations, and times
  • registrations_registrations_relationships - Links registrations to signups and people
  • registrations_attendees_relationships - Links attendees to signups, registrations, and emergency contacts

We'll show you exactly how to join these tables in our examples!

Key Concepts

Registration Status

  • active - Currently registered attendee
  • canceled - Registration was canceled
  • waitlisted - On the waiting list

Signup Status

  • archived - Event is archived (not active)
  • open_at/close_at - Registration window timing

Selection Types

  • Pricing tiers for different attendee types
  • Public vs. private availability
  • Price stored in cents (divide by 100 for dollars)

Sample Insights

Find Events with Waitlists

-- Events with waitlists and conversion potential
SELECT 
    s.name as event_name,
    st.starts_at as event_date,
    COUNT(CASE WHEN a.active = true THEN 1 END) as registered_count,
    COUNT(CASE WHEN a.waitlisted = true THEN 1 END) as waitlist_count,
    sl.name as location_name
FROM planning_center.registrations_signups s
LEFT JOIN planning_center.registrations_signups_relationships sr 
    ON sr.signup_id = s.signup_id 
    AND sr.relationship_type IN ('SignupTime', 'signup_time')
LEFT JOIN planning_center.registrations_signup_times st 
    ON st.signup_time_id = sr.relationship_id
LEFT JOIN planning_center.registrations_signups_relationships slr 
    ON slr.signup_id = s.signup_id 
    AND slr.relationship_type IN ('SignupLocation', 'signup_location')
LEFT JOIN planning_center.registrations_signup_locations sl 
    ON sl.signup_location_id = slr.relationship_id
LEFT JOIN planning_center.registrations_attendees a 
    ON EXISTS (
        SELECT 1
        FROM planning_center.registrations_attendees_relationships ar
        JOIN planning_center.registrations_registrations_relationships rr
            ON rr.registration_id = ar.relationship_id
            AND rr.relationship_type IN ('Signup', 'signup')
        WHERE ar.attendee_id = a.attendee_id
        AND ar.relationship_type IN ('Registration', 'registration')
        AND rr.relationship_id = s.signup_id
    )
WHERE s.archived = false
  AND st.starts_at >= CURRENT_DATE
GROUP BY s.name, st.starts_at, sl.name
HAVING COUNT(CASE WHEN a.waitlisted = true THEN 1 END) > 0
ORDER BY st.starts_at;

Registration Timeline Analysis

-- Registration patterns by days before event
WITH registration_timeline AS (
    SELECT 
        s.name as event_name,
        st.starts_at as event_date,
        a.created_at as registration_date,
        DATE_PART('day', st.starts_at - a.created_at) as days_before_event
    FROM planning_center.registrations_attendees a
    JOIN planning_center.registrations_attendees_relationships ar
        ON ar.attendee_id = a.attendee_id
        AND ar.relationship_type IN ('Registration', 'registration')
    JOIN planning_center.registrations_registrations_relationships ar_sg
        ON ar_sg.registration_id = ar.relationship_id
        AND ar_sg.relationship_type IN ('Signup', 'signup')
    JOIN planning_center.registrations_signups s 
        ON s.signup_id = ar_sg.relationship_id
    JOIN planning_center.registrations_signups_relationships sr 
        ON sr.signup_id = s.signup_id 
        AND sr.relationship_type IN ('SignupTime', 'signup_time')
    JOIN planning_center.registrations_signup_times st 
        ON st.signup_time_id = sr.relationship_id
    WHERE a.active = true
),
windowed AS (
    SELECT 
        CASE 
            WHEN days_before_event >= 30 THEN '30+ days'
            WHEN days_before_event >= 14 THEN '14-29 days'
            WHEN days_before_event >= 7 THEN '7-13 days'
            WHEN days_before_event >= 1 THEN '1-6 days'
            ELSE 'Day of event'
        END as registration_window
    FROM registration_timeline
    WHERE days_before_event >= 0
)
SELECT 
    registration_window,
    COUNT(*) as registration_count,
    ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 2) as percentage
FROM windowed
GROUP BY registration_window
ORDER BY 
    CASE registration_window
        WHEN '30+ days' THEN 1
        WHEN '14-29 days' THEN 2
        WHEN '7-13 days' THEN 3
        WHEN '1-6 days' THEN 4
        WHEN 'Day of event' THEN 5
    END;

Best Practices

  1. Always filter by archived status - Exclude archived events for current reporting
  2. Join through relationship tables - Use the relationship tables to connect entities
  3. Consider waitlist status - Check both active and waitlisted fields for accurate counts
  4. Handle pricing in cents - Remember to divide price_cents by 100 for dollar amounts
  5. Use time zone awareness - Event times are stored with timezone information

Ready to Dive Deeper?

Explore our comprehensive guides to master Planning Center Registrations queries and build powerful event management insights for your ministry.

On this page