EQL for SQL Experts#
If you are coming from a relational database background, EQL will feel familiar but with several powerful abstractions that simplify complex queries. This guide compares EQL concepts with their SQL equivalents.
Implicit JOINs vs. Path Following#
The biggest difference between SQL and EQL is how relationships are handled. In SQL, you must explicitly JOIN tables using foreign keys. In EQL, you simply follow the attribute path.
SQL (Explicit JOIN)#
SELECT p.name
FROM robots r
JOIN parts p ON r.id = p.robot_id
WHERE r.type = 'Astromech'
AND p.status = 'Broken';
EQL (Implicit Path Following)#
# EQL automatically traverses the relationship from robot to parts
query = entity(r.parts.name).where(
r.type == "Astromech",
r.parts.status == "Broken"
)
Filter Early, Filter Late#
In SQL, all filtering happens in the WHERE or HAVING clause. EQL also maintains this distinction.
SQL Clause |
EQL Method |
Purpose |
|---|---|---|
|
|
Filters individual entities before grouping. |
|
|
Defines the grouping keys. |
|
|
Filters aggregated groups after calculation. |
|
|
Sorts the final result set. |
|
|
Restricts the number of returned rows. |
Result Cardinality#
SQL queries always return a result set (even if empty). EQL uses quantifiers to express expectations about the result set size, which helps catch data integrity issues early.
SQL: Always returns 0..N rows.
EQL
an(): Expects 0..N results.EQL
the(): Expects exactly 1 result (likeSELECT ... LIMIT 1but with an assertion).
Note
EQL’s the() is a great way to enforce domain cardinality logic (e.g., “every robot must have exactly
one serial number”) directly in your query.
Set Operations#
Summary Example: A Complex Report#
SQL query:
SQL version:
SELECT type, COUNT(*), AVG(battery)
FROM robots
WHERE online = true
GROUP BY type
HAVING COUNT(*) > 2
ORDER BY AVG(battery) DESC
LIMIT 5
EQL query:
r = variable(ExampleRobot, domain=all_robots)
query = set_of(r.type, count(r), average(r.battery)) \
.where(r.online) \
.grouped_by(r.type) \
.having(count(r) > 2) \
.ordered_by(average(r.battery), descending=True) \
.limit(5)
Warning
While EQL is powerful, remember that it operates on objects in memory. For extremely large datasets typically found in data warehouses, SQL is still the preferred tool. EQL is optimized for complex symbolic reasoning over structured object models. If your case includes calling functions/predicates as part of the query, or if you prefer to work on live domain objects then EQL is the way to go.