Writing Custom Queries
Warehouse and database data sources like BigQuery, Snowflake, Redshift, PostgreSQL, MySQL, and SQL Server let you write custom SQL queries to pull exactly the data you need into WasteNot. This guide covers how to structure your queries so WasteNot can process the results correctly.
This guide is primarily for your engineering or data team. Share it with whoever will be writing the SQL queries for your warehouse streams.
How it works
When you create a stream on a warehouse data source, you provide a SQL query. WasteNot runs this query on a schedule, and each row in the result set becomes an event in WasteNot. These events are what power your audience rules.
WasteNot passes two timestamp parameters to your query for incremental syncing: the start and end of the time window to fetch. Use a half-open range that includes the start and excludes the end. This keeps an event on the boundary from being selected in two consecutive runs.
BigQuery
BigQuery uses named parameters. Reference them with @start_datetime and @end_datetime:
WHERE created_at >= @start_datetime
AND created_at < @end_datetime
Snowflake and MySQL
These databases use positional placeholders. The first ? is the start time, the second ? is the end time:
WHERE created_at >= ?
AND created_at < ?
PostgreSQL and Redshift
Use $1 for the start time and $2 for the end time:
WHERE created_at >= $1
AND created_at < $2
SQL Server
Use @1 for the start time and @2 for the end time:
WHERE created_at >= @1
AND created_at < @2
Required columns
Your query must return rows with the following columns. Column names are case-insensitive.
id (required)
A unique identifier for each row. This must be stable across runs — the same event should always produce the same ID. WasteNot uses this to deduplicate data.
occurred_at (required)
A timestamp for when the event happened. WasteNot uses this for time-based audience rules (e.g., "customers who ordered in the last 30 days"). This should be a TIMESTAMP or DATETIME type.
email or phone or customer_id (at least one required)
WasteNot needs a way to identify who the event belongs to. Provide at least one of:
email— The customer's email address (preferred, used for ad platform matching)phone— The customer's phone numbercustomer_id— An internal customer identifier from your system
WasteNot resolves identity in this priority order: email first, then phone, then customer_id. If you can provide email, that gives the best match rates when syncing audiences to ad platforms.
value (optional)
A numeric value associated with the event (e.g., order total, charge amount). Defaults to 0. Used for value-based audience rules like "customers who spent more than $100."
Event types
When creating a stream, you choose an Event Type that tells WasteNot what kind of data the query returns. This determines how the data is used in audience rules. You can select from commerce events (orders, refunds, charges), email events (opens, clicks, bounces), SMS events, and session events. The full list is available in the stream creation form.
Example queries
Orders (BigQuery)
SELECT
CAST(order_id AS STRING) AS id,
customer_email AS email,
order_total AS value,
created_at AS occurred_at
FROM `my_project.shopify.orders`
WHERE created_at >= @start_datetime
AND created_at < @end_datetime
Orders (Snowflake)
SELECT
order_id AS id,
email,
order_total AS value,
created_at AS occurred_at
FROM orders
WHERE created_at >= ?
AND created_at < ?
Email engagement (BigQuery)
SELECT
CAST(event_id AS STRING) AS id,
recipient_email AS email,
opened_at AS occurred_at
FROM `my_project.email.events`
WHERE event_type = 'open'
AND opened_at >= @start_datetime
AND opened_at < @end_datetime
Refunds with customer ID fallback (BigQuery)
SELECT
CAST(refund_id AS STRING) AS id,
customer_email AS email,
CAST(customer_id AS STRING) AS customer_id,
refund_amount AS value,
refunded_at AS occurred_at
FROM `my_project.shopify.refunds`
WHERE refunded_at >= @start_datetime
AND refunded_at < @end_datetime
Tips
- Always use the half-open time window. Include the start and exclude the end so WasteNot can sync incrementally without selecting boundary events twice.
- Use stable IDs. If the same row gets a different
idon each run, WasteNot will create duplicates. - Provide email when possible. Email gives the best match rate when syncing audiences to ad platforms like Google Ads and Facebook.
- Keep queries efficient. WasteNot runs these on a schedule, so make sure your query performs well on your warehouse. Use partitioned or clustered tables where possible.
Creating a stream
- Go to your warehouse data source detail page in WasteNot
- Click New Stream
- Enter a Name for the stream
- Select the Event Type that matches your data
- Paste your SQL query
- Enable the stream and click Save
WasteNot will begin running your query on a schedule and syncing the results automatically.