SQL validation examples

See How Easily AI Validates and Fixes SQL

Explore common SQL validation errors and review corrected queries before running them in production. Each example includes an invalid SQL query, a step-by-step explanation of the issues, and a corrected version.

  • Compare invalid SQL and corrected SQL side by side
  • Understand common SQL syntax and semantic validation errors for all common databases
  • Use practical fixes for JOIN, aggregation, alias, and window-function mistakes
  • Improve SQL quality before optimization, formatting, or deployment

What these SQL validator examples cover

This page focuses on SQL validation workflows for PostgreSQL queries: syntax checks, clause ordering, alias scope, JOIN correctness, aggregate rules, and window-function usage.

Use these examples to identify and fix invalid SQL quickly before handing queries off to your formatter, optimizer, or execution pipeline.

SQL validator examples

Review common SQL validation failures and corrected PostgreSQL queries. Each example shows the invalid input, precise issue list, and a fixed query.

Example 1: Missing FROM clause

Invalid SQL input

SELECT
  user_id,
  email
users
WHERE
  is_active = true;

Validator output

❌ Validation errors

SELECT
  user_id,
  email
-- 1. Missing FROM before the source table:
users
WHERE
  is_active = true;

💬 Explanation

#Explanation
1The 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;
Example 2: Trailing comma in SELECT list

Invalid SQL input

SELECT
  product_name,
  price,
  category,
FROM
  products;

Validator output

❌ Validation errors

SELECT
  product_name,
  price,
  -- 1. Trailing comma before FROM:
  category,
FROM
  products;

💬 Explanation

#Explanation
1PostgreSQL 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;
Example 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;

Validator output

❌ 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
1WHERE 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;
Example 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;

Validator output

❌ 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
1o.order_date references alias o, but no table was declared with alias o.
2Every JOIN must specify a table or subquery to join.
3The 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;
Example 5: Aggregation without GROUP BY

Invalid SQL input

SELECT
  department,
  AVG(salary)
FROM
  employees
HAVING
  department = 'Sales';

Validator output

❌ 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
1When aggregate functions are used, non-aggregated columns in SELECT must appear in GROUP BY.
2Use 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;
Example 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;

Validator output

❌ 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
1Window 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;
Example 7: INSERT column/value count mismatch

Invalid SQL input

INSERT INTO users (
  username,
  email,
  is_active
)
VALUES (
  'alice',
  'alice@example.com'
);

Validator output

❌ Validation errors

INSERT INTO users (
  username,
  email,
  is_active
)
VALUES (
  -- 1. Only two values for three target columns:
  'alice',
  'alice@example.com'
);

💬 Explanation

#Explanation
1The 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
);
Example 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';

Validator output

❌ 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
1The CTE only returns sales_month and revenue; region_name is not part of its schema.
2Filters 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';

SQL validation checklist

Use this checklist before running SQL in staging or production to reduce preventable syntax and structure errors.

  • Confirm every SELECT query has valid FROM sources and correctly declared table aliases.
  • Check that SELECT aliases are only used where scope rules allow (not in WHERE).
  • Validate aggregation rules: every non-aggregated selected column must be grouped.
  • Review INSERT target columns and VALUES count/type compatibility before execution.

After validation, continue with the SQL formatter, SQL optimizer, and SQL explainer to improve readability, performance, and documentation quality.

SQL validator FAQ

What does an SQL validator check?

An SQL validator checks query syntax and structural correctness, including clause order, alias scope, JOIN structure, and aggregate rules. It helps catch errors before execution.

Can SQL validation prevent runtime issues?

Validation catches many issues early, but not all runtime problems. You should still test against real schemas, permissions, and data distributions to validate behavior end-to-end.

Should I validate SQL before formatting or optimization?

Yes. Validate first so downstream formatting and optimization steps work on correct SQL. Then format for readability and optimize based on execution plans.