SQL validation examples
SQL Validator Examples
Common SQL mistakes paired with the exact fix — syntax, alias scope, joins, aggregation, and window functions.
Examples use PostgreSQL syntax. The same validation rules apply across all 28 supported databases — MySQL, SQL Server, Oracle, BigQuery, Snowflake, and more.
1. Missing FROM clause
Invalid SQL input
SELECT
user_id,
email
users
WHERE
is_active = true; ❌ Validation errors
SELECT
user_id,
email
-- 1. Missing FROM before the source table:
users
WHERE
is_active = true;
💬 Explanation
| # | Explanation |
|---|---|
| 1 | The SELECT statement is missing FROM users. PostgreSQL requires FROM to define the row source before WHERE filters are applied. |
🚀 Corrected SQL query
SELECT
user_id,
email
FROM users
WHERE
is_active = true;2. Trailing comma in SELECT list
Invalid SQL input
SELECT
product_name,
price,
category,
FROM
products; ❌ Validation errors
SELECT
product_name,
price,
-- 1. Trailing comma before FROM:
category,
FROM
products;
💬 Explanation
| # | Explanation |
|---|---|
| 1 | PostgreSQL does not allow a trailing comma after the last projected column. Remove the comma after category before FROM. |
🚀 Corrected SQL query
SELECT
product_name,
price,
category
FROM
products;3. Alias used in WHERE before SELECT evaluation
Invalid SQL input
SELECT
order_id,
(quantity * unit_price) AS total_value
FROM
order_details
WHERE
total_value > 1000; ❌ Validation errors
SELECT
order_id,
(quantity * unit_price) AS total_value
FROM
order_details
WHERE
-- 1. SELECT alias is not visible in WHERE:
total_value > 1000;
💬 Explanation
| # | Explanation |
|---|---|
| 1 | WHERE runs before SELECT aliases are created, so total_value is undefined in this clause. Repeat the expression or use a subquery/CTE. |
🚀 Corrected SQL query
SELECT
order_id,
(quantity * unit_price) AS total_value
FROM
order_details
WHERE
(quantity * unit_price) > 1000;4. JOIN missing target table and alias
Invalid SQL input
SELECT
c.customer_name,
o.order_date
FROM
customers c
JOIN
ON c.id = o.customer_id; ❌ Validation errors
SELECT
c.customer_name,
-- 1. Alias "o" is referenced but never defined:
o.order_date
FROM
customers c
-- 2. JOIN target table is missing:
JOIN
-- 3. ON cannot appear without a valid JOIN target:
ON c.id = o.customer_id;
💬 Explanation
| # | Explanation |
|---|---|
| 1 | o.order_date references alias o, but no table was declared with alias o. |
| 2 | Every JOIN must specify a table or subquery to join. |
| 3 | The ON predicate is only valid after a complete JOIN target declaration, such as JOIN orders o. |
🚀 Corrected SQL query
SELECT
c.customer_name,
o.order_date
FROM
customers c
JOIN
orders o
ON c.id = o.customer_id;5. Aggregation without GROUP BY
Invalid SQL input
SELECT
department,
AVG(salary)
FROM
employees
HAVING
department = 'Sales'; ❌ Validation errors
SELECT
-- 1. Non-aggregated department is selected with AVG without grouping:
department,
AVG(salary)
FROM
employees
HAVING
-- 2. HAVING is used to filter detail rows instead of grouped results:
department = 'Sales';
💬 Explanation
| # | Explanation |
|---|---|
| 1 | When aggregate functions are used, non-aggregated columns in SELECT must appear in GROUP BY. |
| 2 | Use WHERE for row-level filtering (pre-aggregation) and HAVING for aggregate/group-level filtering (post-aggregation). |
🚀 Corrected SQL query
SELECT
department,
AVG(salary) AS avg_salary
FROM
employees
WHERE
department = 'Sales'
GROUP BY
department;6. Invalid WHERE inside window OVER clause
Invalid SQL input
SELECT
employee_name,
salary,
department,
SUM(salary) OVER (PARTITION BY department WHERE is_manager = false ORDER BY hire_date) AS running_total
FROM
employees; ❌ Validation errors
SELECT
employee_name,
salary,
department,
-- 1. OVER(...) does not allow WHERE:
SUM(salary) OVER (PARTITION BY department WHERE is_manager = false ORDER BY hire_date) AS running_total
FROM
employees;
💬 Explanation
| # | Explanation |
|---|---|
| 1 | Window definitions only allow PARTITION BY, ORDER BY, and frame clauses. Put conditional logic in FILTER (WHERE ...) or a CASE expression. |
🚀 Corrected SQL query
SELECT
employee_name,
salary,
department,
SUM(salary) FILTER (WHERE NOT is_manager) OVER (
PARTITION BY department
ORDER BY hire_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total
FROM
employees;7. INSERT column/value count mismatch
Invalid SQL input
INSERT INTO users (
username,
email,
is_active
)
VALUES (
'alice',
'alice@example.com'
); ❌ Validation errors
INSERT INTO users (
username,
email,
is_active
)
VALUES (
-- 1. Only two values for three target columns:
'alice',
'alice@example.com'
);
💬 Explanation
| # | Explanation |
|---|---|
| 1 | The INSERT target list has three columns, but VALUES provides only two entries. PostgreSQL raises a column/value count mismatch error. |
🚀 Corrected SQL query
INSERT INTO users (
username,
email,
is_active
)
VALUES (
'alice',
'alice@example.com',
true
);8. CTE referenced without join target
Invalid SQL input
WITH monthly_revenue AS (
SELECT
date_trunc('month', order_date)::date AS sales_month,
SUM(total_amount) AS revenue
FROM orders
GROUP BY 1
)
SELECT
sales_month,
revenue,
region_name
FROM
monthly_revenue
WHERE
region_name = 'North America'; ❌ Validation errors
WITH monthly_revenue AS (
SELECT
date_trunc('month', order_date)::date AS sales_month,
SUM(total_amount) AS revenue
FROM orders
GROUP BY 1
)
SELECT
sales_month,
revenue,
-- 1. region_name is not produced by monthly_revenue:
region_name
FROM
monthly_revenue
WHERE
-- 2. region_name filter references an undefined column:
region_name = 'North America';
💬 Explanation
| # | Explanation |
|---|---|
| 1 | The CTE only returns sales_month and revenue; region_name is not part of its schema. |
| 2 | Filters can only reference columns available from the current FROM scope. Add a join to a source that contains region_name. |
🚀 Corrected SQL query
WITH monthly_revenue AS (
SELECT
date_trunc('month', o.order_date)::date AS sales_month,
o.region_name,
SUM(o.total_amount) AS revenue
FROM orders o
GROUP BY
date_trunc('month', o.order_date)::date,
o.region_name
)
SELECT
sales_month,
revenue,
region_name
FROM
monthly_revenue
WHERE
region_name = 'North America';Try these on your own queries
Generate, optimize, validate, explain, and format SQL with the SQLAI.ai tools — across every supported database.