A collection of SQL query patterns that work across all Retool templates. Copy these into your Retool queries and adjust table/column names for your schema.
-- Offset-based pagination (works with Retool's table component)
SELECT *
FROM your_table
ORDER BY created_at DESC
LIMIT {{table1.pageSize}}
OFFSET {{table1.paginationOffset}}-- Case-insensitive search across multiple columns
SELECT *
FROM your_table
WHERE (
{{searchInput.value}} = ''
OR name ILIKE '%' || {{searchInput.value}} || '%'
OR email ILIKE '%' || {{searchInput.value}} || '%'
OR id::text = {{searchInput.value}}
)-- Filter by date range picker component
SELECT *
FROM your_table
WHERE created_at BETWEEN {{dateRange.start}} AND {{dateRange.end}}-- Dashboard statistics with conditional aggregation
SELECT
COUNT(*) as total,
COUNT(*) FILTER (WHERE status = 'active') as active_count,
COUNT(*) FILTER (WHERE created_at >= CURRENT_DATE) as today_count,
ROUND(AVG(some_metric), 2) as avg_metric
FROM your_table
WHERE created_at >= CURRENT_DATE - INTERVAL '30 days'-- Insert or update based on a unique key
INSERT INTO your_table (unique_key, name, value, updated_at)
VALUES ({{form.data.key}}, {{form.data.name}}, {{form.data.value}}, NOW())
ON CONFLICT (unique_key) DO UPDATE SET
name = EXCLUDED.name,
value = EXCLUDED.value,
updated_at = NOW()-- Soft delete with audit trail
UPDATE your_table
SET
status = 'deleted',
deleted_at = NOW(),
deleted_by = {{current_user.id}}
WHERE id = {{table1.selectedRow.id}}-- Log an action to an audit trail
INSERT INTO audit_logs (user_id, action, resource_type, resource_id, metadata, ip_address, created_at)
VALUES (
{{current_user.id}},
'update',
'order',
{{table1.selectedRow.id}},
jsonb_build_object('old_status', {{table1.selectedRow.status}}, 'new_status', {{statusSelect.value}}),
{{current_user.ip}},
NOW()
)-- Bulk update using selected rows from a table
UPDATE your_table
SET status = {{statusSelect.value}}, updated_at = NOW()
WHERE id = ANY(ARRAY[{{table1.selectedRows.map(r => r.id).join(',')}}]::int[])-- Generate time-series data for chart components
SELECT
DATE(created_at) as date,
COUNT(*) as count,
SUM(amount) as total_amount
FROM your_table
WHERE created_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY DATE(created_at)
ORDER BY dateBefore importing templates, you need to configure at least one data source (called a "Resource" in Retool).
1. Go to Resources in the top navigation
2. Click "Create new" → PostgreSQL
3. Fill in:
4. Click "Test connection" then "Create resource"
1. Go to Resources → "Create new" → REST API
2. Configure:
https://api.example.com/v1Authorization: Bearer YOUR_TOKEN3. These templates reference REST APIs for some integrations
Same as PostgreSQL, but select MySQL as the resource type. Port default is 3306.
Set up environment variables in Retool for values that differ between staging and production:
1. Go to Settings → Environment Variables
2. Add variables like:
DATABASE_HOSTAPI_BASE_URLSLACK_WEBHOOK_URL3. Reference them in queries as {{env.DATABASE_HOST}}