Best Overall
Claude
Careful with “only columns I pasted.”
Open Claudelearn · ~25 min
Read-only by default. The model must not invent tables or columns. Every answer needs an ASSUMPTIONS list. Never run destructive SQL blind—DELETE / UPDATE / DROP / TRUNCATE / ALTER needs a warning, ALLOW DESTRUCTIVE, a preview SELECT, and a backup you control.
Best Overall
Careful with “only columns I pasted.”
Open ClaudeBest Free
Enough for one careful paste-and-review session.
Open ChatGPTBest Power-User
Draft here; run EXPLAIN in your own warehouse.
Open GeminiInclude dialect (PostgreSQL, MySQL, BigQuery, SQL Server, SQLite), CREATE TABLE or a column list, grain/keys if you know them, and the question in one sentence. If a table is not in the paste, it does not exist for this chat.
Paste the rules before the schema so the model cannot hallucinate a users.email column.
Copy-paste prompt
Write SQL from a schema and a plain-English goal I will paste. Hard rules: - Use only tables and columns in my schema paste. Never invent a table, column, type, or join key. - If the goal needs a column I did not give, stop and list NEED FROM SCHEMA. Do not guess. - Default to a read-only SELECT (or WITH … SELECT). - Before any DELETE, UPDATE, DROP, TRUNCATE, MERGE, or ALTER: print a WARNING block (what rows/objects, what is irreversible) and wait for me to type ALLOW DESTRUCTIVE. - State dialect-specific functions only for the dialect I name. - Show assumptions separately from the SQL. Output: 1) Restated goal 2) SQL 3) Assumptions 4) NEED FROM SCHEMA 5) How I should sanity-check the result (using only my columns) Confirm the rules, then wait.
Read the ASSUMPTIONS list and NEED FROM SCHEMA before you run anything. If a join key was assumed, fix the schema paste and regenerate. Never run destructive SQL blind.
Generate command
Dialect, schema, and goal are below. Write the SELECT. If you must invent a column, do not—list it under NEED FROM SCHEMA. No destructive SQL unless I later type ALLOW DESTRUCTIVE.
You still execute. Prefer EXPLAIN or a LIMIT first. If you truly need a mutating statement, use the block below only after a backup you control.
Destructive-SQL gate
I typed ALLOW DESTRUCTIVE. Rewrite as the mutating statement I described, with a WARNING (object, filter, irreversibility) above the SQL, and a SELECT that previews matching rows using only my schema. If the filter is missing, refuse.