SQL Query Building
Standard routes automatically generate SQL based on your configuration. This page covers all the components that make up a SQL query.
Base Table
Section titled “Base Table”The primary table this route queries. Determines which columns are available for filtering and response mapping.
Example: For a user profile endpoint, the base table would be user.
Combine data from related tables to include information from multiple tables in your response.
Join Properties
Section titled “Join Properties”| Property | Description |
|---|---|
| Table | The related table to join |
| Local Column | The foreign key column in your base (or joined) table |
| Foreign Column | The column in the related table (typically id) |
| Type | Join type: INNER or LEFT |
| Alias | Short name for referencing joined columns |
Join Types
Section titled “Join Types”| Type | Description |
|---|---|
| INNER | Only returns rows where matching records exist in both tables |
| LEFT | Returns all rows from the left table, with NULL for non-matching right table rows |
When to use INNER:
- When the relationship is required (e.g., every order must have a user)
- When you only want results where both sides exist
When to use LEFT:
- When the relationship is optional (e.g., a user might not have a manager)
- When you want all base table rows regardless of whether related data exists
Join Alias Convention
Section titled “Join Alias Convention”Aliases follow the format: {localColumn}_{foreignTable}
Example: Joining user.companyId to company.id creates alias companyId_company
This allows you to reference the joined table’s columns:
companyId_company.name→ Company namecompanyId_company.address→ Company address
Join Example
Section titled “Join Example”Base table: order
Join configuration:
Table: userLocal Column: order.userIdForeign Column: user.idType: INNERAlias: userId_userGenerated SQL:
SELECT ...FROM "order"INNER JOIN "user" AS "userId_user" ON "order"."userId" = "userId_user"."id"Now you can use userId_user.firstName, userId_user.email, etc. in your response properties.
Where Clauses
Section titled “Where Clauses”Filter which rows are returned or affected by your query.
Where Clause Properties
Section titled “Where Clause Properties”| Property | Description |
|---|---|
| Table | The table containing the column to filter |
| Column | The column to compare |
| Operator | The comparison type |
| Value | The value to compare against (can use $param or #global) |
| Conjunction | Logical connector to previous condition (AND or OR) |
| Custom | Raw SQL expression (alternative to column-based filter) |
Operators
Section titled “Operators”| Operator | Description | Example |
|---|---|---|
= | Equals | user.id = $id |
!= | Not equals | status != 'deleted' |
< | Less than | price < $maxPrice |
> | Greater than | createdOn > $since |
<= | Less than or equal | quantity <= $max |
>= | Greater than or equal | age >= 18 |
LIKE | Pattern match (use % wildcard) | name LIKE $search |
NOT LIKE | Negative pattern match | email NOT LIKE '%test%' |
IN | Match any value in set | status IN $statuses |
NOT IN | Exclude values in set | role NOT IN ('guest') |
STARTS WITH | String prefix match | name STARTS WITH $prefix |
ENDS WITH | String suffix match | email ENDS WITH $domain |
IS | Identity comparison | deletedOn IS NULL |
IS NOT | Negative identity | manager IS NOT NULL |
Where Clause Examples
Section titled “Where Clause Examples”Simple equality:
Table: userColumn: idOperator: =Value: $userIdPattern matching:
Table: userColumn: emailOperator: LIKEValue: %$searchTerm%Status filtering:
Table: orderColumn: statusOperator: INValue: $statusesDate range:
Table: orderColumn: createdOnOperator: >=Value: $startDateConjunction: AND
Table: orderColumn: createdOnOperator: <=Value: $endDateCustom SQL:
Custom: "user"."firstName" || ' ' || "user"."lastName" LIKE $fullNameOrder By
Section titled “Order By”Sort query results (available for ARRAY and PAGED types).
Order By Properties
Section titled “Order By Properties”| Property | Description |
|---|---|
| Table | Table containing the sort column |
| Column | Column to sort by |
| Order | Direction: ASC or DESC |
Examples
Section titled “Examples”Sort by creation date (newest first):
Table: orderColumn: createdOnOrder: DESCSort by name (alphabetical):
Table: userColumn: lastNameOrder: ASCMultiple sort columns:
1. Table: user, Column: lastName, Order: ASC2. Table: user, Column: firstName, Order: ASCGroup By
Section titled “Group By”Aggregate rows by a column value.
Group By Properties
Section titled “Group By Properties”| Property | Description |
|---|---|
| Table | Table containing the group column |
| Column | Column to group by |
Example: Count Orders by User
Section titled “Example: Count Orders by User”Base table: order
Group by: order.userId
Response properties:
userId→order.userIdorderCount→COUNT(*)
Generated SQL:
SELECT "order"."userId", COUNT(*) as "orderCount"FROM "order"GROUP BY "order"."userId"Assignments
Section titled “Assignments”Value mappings for INSERT/UPDATE operations (POST, PUT, PATCH methods).
Assignment Properties
Section titled “Assignment Properties”| Property | Description |
|---|---|
| Name | The column name to assign a value to |
| Value | The value to assign (can use $param or #global) |
Examples
Section titled “Examples”Create user (POST):
firstName = $firstNamelastName = $lastNameemail = $emailcompanyId = #companyIdcreatedOn = now()Update user status (PATCH):
status = $statusmodifiedOn = now()Set ownership (POST):
userId = #userIdcompanyId = #companyIdSubqueries
Section titled “Subqueries”Nested queries within a response that fetch related data from another table.
Subquery Properties
Section titled “Subquery Properties”| Property | Description |
|---|---|
| Table | The related table to query |
| Joins | Additional joins within the subquery |
| Where | Conditions to filter subquery results |
| Properties | Fields to return from the subquery |
| Group By | Optional grouping |
| Order By | Optional sorting |
Example: User with Orders
Section titled “Example: User with Orders”Base table: user
Response properties:
id→user.idname→user.firstNameorders→ Subquery
Subquery configuration:
Table: orderWhere: order.userId = user.idProperties: - id → order.id - total → order.total - status → order.statusOrder By: order.createdOn DESCResponse:
{ "data": { "id": 1, "name": "John", "orders": [ { "id": 101, "total": "299.99", "status": "completed" }, { "id": 102, "total": "149.99", "status": "pending" } ] }}Complete Example
Section titled “Complete Example”Endpoint: Get user profile with company and recent orders
Base table: user
Joins:
Table: companyLocal: user.companyIdForeign: company.idType: LEFTAlias: companyId_companyWhere clauses:
user.id = $userIdAND user.status != 'deleted'Response properties:
id → user.idfirstName → user.firstNamelastName → user.lastNameemail → user.emailcompanyName → companyId_company.nameorders → [subquery]Subquery (orders):
Table: orderWhere: order.userId = user.idOrder By: order.createdOn DESCLimit: 5Properties: - id → order.id - total → order.total - status → order.status - createdOn → order.createdOn