SQL Comments

A comment in SQL is text inside a query that the database engine completely ignores when it parses and executes the statement. Comments exist purely for humans: to explain intent, leave notes for teammates, or temporarily disable part of a query while testing. Every serious SQL codebase uses them, and knowing exactly how they’re parsed (and where they silently go wrong) will save you from some very confusing bugs.

Overview: How Comments Work

Before your database engine builds a query plan, it runs a lexical analysis (tokenizing) pass over the raw text of your SQL. During this pass, anything recognized as a comment is stripped out entirely — as if it were never typed. The parser that comes after never even sees the comment; it only sees the tokens (keywords, identifiers, operators) that remain. This is why a comment can never accidentally change how a query behaves: from the engine’s point of view, a commented-out clause simply does not exist.

SQL supports two comment styles, and almost every relational database (SQLite, MySQL, PostgreSQL, SQL Server, Oracle) supports both:

  • Single-line comments start with two hyphens -- and run to the end of the physical line.
  • Multi-line (block) comments start with /* and end with the first */ found, and can span any number of lines.

MySQL additionally allows # to start a single-line comment, but that is a MySQL-specific extension — it is not standard SQL and will not work in SQLite, PostgreSQL, or SQL Server, so it’s best avoided if you want portable code.

Syntax

Style Syntax Scope Portability
Single-line -- comment text From -- to end of that line Standard SQL — works everywhere
Multi-line /* comment text */ Everything between /* and the first */ Standard SQL — works everywhere
Hash (MySQL only) # comment text From # to end of that line MySQL-specific, not portable

Comments can appear almost anywhere whitespace is allowed: on their own line above a statement, trailing at the end of a line of code, or in the middle of a clause between two tokens.

Examples

Example 1: A trailing single-line comment

-- Show only the name and salary columns for Engineering staff
SELECT name, salary
FROM employees
WHERE department = 'Engineering'; -- filter applied

Result: exactly the same rows you would get without either comment — every employee row whose department equals 'Engineering', with just the name and salary columns returned. The two -- comments contribute nothing to execution; they only document what the query does and why the filter is there.

Example 2: A multi-line comment documenting a report

CREATE TABLE inventory (
    item_id INTEGER PRIMARY KEY,
    item_name TEXT,
    quantity INTEGER,
    price REAL
);

INSERT INTO inventory (item_id, item_name, quantity, price) VALUES
    (1, 'Widget', 50, 2.50),
    (2, 'Gadget', 12, 9.99),
    (3, 'Gizmo', 0, 15.00);

/* This report lists items that are currently in stock.
   Out-of-stock items (quantity = 0) are excluded below. */
SELECT item_name, quantity, price
FROM inventory
WHERE quantity > 0
ORDER BY item_name;
item_name quantity price
Gadget 12 9.99
Widget 50 2.5

Result: two rows — Gadget and Widget — ordered alphabetically by item_name. Gizmo is excluded because its quantity is 0. The block comment above the query explains the business rule (why out-of-stock items are filtered) so the next person reading the file doesn’t have to reverse-engineer the WHERE clause.

Example 3: Using a comment to temporarily disable a column

CREATE TABLE employees_demo (
    id INTEGER PRIMARY KEY,
    name TEXT,
    department TEXT,
    salary REAL
);

INSERT INTO employees_demo (id, name, department, salary) VALUES
    (1, 'Alice', 'Engineering', 95000),
    (2, 'Ben', 'Sales', 62000),
    (3, 'Carla', 'Engineering', 88000);

SELECT
    name,
    department,
    salary
    -- , salary * 0.1 AS bonus   -- disabled until bonus rules are finalized
FROM employees_demo
WHERE department = 'Engineering'
ORDER BY salary DESC;
name department salary
Alice Engineering 95000.0
Carla Engineering 88000.0

Result: only two rows for the Engineering department, sorted by salary descending, and no bonus column, because that column expression is commented out. This is one of the most common real-world uses of comments: developers routinely comment out a column, a join, or a WHERE condition while debugging a query, without deleting the code — it can be re-enabled just by removing the --.

How It Works Step by Step

Comments are removed at the very first stage of processing, before the logical query steps (FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT) ever begin:

  1. Tokenizing: the engine scans the raw text character by character. When it sees --, it discards everything up to the next newline. When it sees /*, it discards everything up to the matching */, including newlines in between.
  2. Parsing: the remaining tokens (keywords, identifiers, literals, punctuation) are assembled into a syntax tree. Since the comment text was already removed, the parser has no idea a comment was ever there.
  3. Planning & execution: the query plan is built and the statement runs against the tables exactly as if the comments had been deleted from the file by hand.

Because stripping happens first, a comment can sit in the middle of a clause — between a column list and its FROM, or between an operator and its value — without breaking anything, as long as valid tokens remain on either side.

Common Mistakes

Mistake 1: Forgetting to close a block comment

SELECT product_name, price
FROM products
/* WHERE category = 'Electronics'
ORDER BY price;

This is broken: the /* is never closed with a matching */, so the comment swallows the rest of the file — including the semicolon that ends the statement. The engine reaches end-of-input still “inside” the comment and raises a syntax error because there is no complete statement left to execute. The fix is to always close every block comment:

SELECT product_name, price
FROM products
/* WHERE category = 'Electronics' */
ORDER BY price;

Note the corrected version comments out only the WHERE clause (so it no longer filters), while ORDER BY price remains active code, outside the comment.

Mistake 2: Nesting block comments

/* Outer comment
   /* inner comment */
   this text is NOT commented out and breaks the query
*/
SELECT * FROM products;

Standard SQL block comments do not nest. The first */ encountered closes the comment — it doesn’t matter that it was meant as the “inner” one. Everything after that first */ (the line this text is NOT commented out… and the stray trailing */) is now treated as real SQL and causes a syntax error. The safe fix is to never place one /* */ block inside another; use -- for the parts you want to remove, or comment out only one region at a time.

Best Practices

  • Write a short comment above complex queries explaining why a filter or join exists, not just what it does — the SQL itself already shows the “what”.
  • Prefer -- for short, single-line notes and quickly disabling one line; reserve /* */ for longer explanations or disabling multi-line blocks.
  • Never nest /* */ comments — if you need to comment out a region that already contains a block comment, switch that inner one to -- lines first.
  • Avoid MySQL’s # comment style in code you want to run on other databases; stick to -- and /* */ for portability.
  • Don’t leave large blocks of dead, commented-out SQL in production scripts indefinitely — use version control to remember old queries, and keep live files clean.
  • Double-check that every /* has a matching */ before running a script, especially after editing near an existing block comment.

Practice Exercises

  • Exercise 1: Write a query against the customers table that selects customer_name and country, with a single-line comment above it explaining that it lists all customers, and a trailing comment noting the column order.
  • Exercise 2: Take a query that joins orders to customers and use a block comment to temporarily remove the ORDER BY clause without deleting it. Confirm the query still runs and returns rows in a different (unspecified) order.
  • Exercise 3: Intentionally write a query with an unterminated /* comment, predict what part of the statement gets swallowed, then fix it by adding the missing */ in the correct place.

Summary

  • Comments are removed during tokenizing, before parsing or execution — they have zero effect on query results.
  • -- comment covers from the two hyphens to the end of that line.
  • /* comment */ can span multiple lines but ends at the very first */ it finds.
  • Block comments do not nest — the first closing */ ends the comment, regardless of intent.
  • An unterminated /* swallows the rest of the script and causes a syntax error.
  • Comments are a core tool for documenting intent and for temporarily disabling parts of a query during debugging.