Install
openclaw skills install text-to-sql-v1Use when (1) user describes what data they want in plain English and asks for the corresponding SQL query. (2) user says "write SQL for this", "convert to query", "how do I select", or "give me the SQL". (3) user provides a database schema or table descriptions and asks a question answerable by SQL.
openclaw skills install text-to-sql-v1Use when (1) user describes what data they want in plain English and asks for the corresponding SQL query. (2) user says "write SQL for this", "convert to query", "how do I select", or "give me the SQL". (3) user provides a database schema or table descriptions and asks a question answerable by SQL.
This skill solves the specific problem of: non-technical users who know what data they want cannot translate their intent into SQL — they need a bridge from natural language to query.
This skill IS NOT:
This skill IS activated ONLY when: natural language description + database schema + SQL request are all present.
/text-to-sqlDefault mode. Converts natural language into a syntactically correct SQL query.
When to use: User describes data needs and provides schema — wants the query.
/text-to-sql/explainOutputs the SQL query with inline comments explaining each clause.
When to use: User wants to understand the query while seeing it, for learning purposes.
/text-to-sql/alternativesProvides 2-3 alternative query approaches (different JOINs, subqueries vs CTEs, etc.).
When to use: User is learning SQL or wants to compare query strategies.
table_name → {column: type}Map natural language intent to SQL components:
| Natural Language | SQL Clause |
|---|---|
| "all", "every", "complete list" | SELECT * or SELECT all columns |
| "only", "just", "specifically" | SELECT [specific columns] |
| "where [condition]" | WHERE clause |
| "sorted by", "in order of" | ORDER BY |
| "grouped by", "each [X]" | GROUP BY |
| "top N", "first N", "N most" | LIMIT N + ORDER BY |
| "not", "exclude", "without" | WHERE NOT or != / <> |
| "both X and Y", "along with" | AND in WHERE, or JOIN |
| "either X or Y", "or" | OR in WHERE |
| "between X and Y" | BETWEEN |
| "like", "containing", "includes" | LIKE '%value%' |
| "before", "after", "earlier than" | WHERE date_column < 'date' |
| "latest", "most recent", "newest" | ORDER BY date DESC LIMIT 1 |
| "count of", "how many" | COUNT(*) aggregate |
| "total of", "sum of" | SUM(column) |
| "average of" | AVG(column) |
If the request involves multiple tables:
INNER JOIN (default), LEFT JOIN (if some side may be empty), RIGHT JOIN (rare)If schema doesn't include relationship info, ask user to clarify which column links the tables.
SELECT
o.order_id,
o.created_at,
c.customer_name,
SUM(o.total_amount) AS total_revenue
FROM orders o
INNER JOIN customers c ON o.customer_id = c.id
WHERE o.created_at >= '2024-01-01'
GROUP BY o.order_id, o.created_at, c.customer_name
ORDER BY total_revenue DESC
LIMIT 10;
Check:
SELECT * in production queries — list specific columnso.order_id)A good output:
A bad output:
SELECT * without justification in a query that should return specific columnsGROUP BY for an aggregate query| Scenario | Bad Output | Good Output |
|---|---|---|
Schema: users(id, name), orders(user_id, total) | SELECT * FROM orders | SELECT u.name, SUM(o.total) FROM users u JOIN orders o ON u.id = o.user_id GROUP BY u.name |
| "top 10 customers" | No LIMIT 10 or ORDER BY | ORDER BY total DESC LIMIT 10 |
| No schema provided | Writes a query with invented columns | "Could you share the table schema (column names and types)?" |
| "show me revenue by month" | SELECT revenue without GROUP BY | SELECT DATE_TRUNC('month', date), SUM(revenue) FROM orders GROUP BY 1 |
references/ — SQL dialect cheat sheet (PostgreSQL, MySQL, SQLite), JOIN types and when to use each, common intent-to-clause mapping