SQL / SELECTING ROWS
Comments that explain the why behind a query
Write SQL comments that record the rule, ticket, or threshold behind a filter, and disable a single predicate without breaking the query.
What you will learn
- Write -- for a line comment and /* ... */ for a block that spans several lines.
- Justify every bare literal in a WHERE clause with the rule or ticket behind it.
- Start each line with AND so one predicate can be disabled with a single --.
- Remember -- swallows the rest of its line, which can silently widen a filter.
Understanding Comments that explain the why behind a query
SQL has two comment forms: -- runs to the end of the line, and /* ... */ spans as many lines as you like. Both are stripped by the parser before the query is planned, so a comment can sit anywhere whitespace can sit, including between two conditions in the middle of a WHERE clause, and it costs nothing at run time. That freedom matters, because the explanation you need usually belongs next to one specific condition rather than in a header far above the statement.
A WHERE clause is a complete record of which rows you kept and a completely silent one about why that boundary is where it is. A comment like -- keep only open tickets adds nothing, since the code already said that, and it turns into a lie the first time the predicate changes. The comment worth writing points at something outside the query: the SLA document that fixed the number, the person who asked for the report, the calibration fault that makes low readings meaningless. A bare literal in a predicate, such as 15 or 'settled', is the strongest signal that a comment is owed, because nobody can derive that value from the schema.
Comments are also a working tool while you narrow a filter down. If every condition starts its own line with AND, disabling one is a single --; if AND trails the end of the previous line, the same edit leaves AND with nothing after it and the statement refuses to parse. The parse error is the friendly outcome. The dangerous edit is a -- placed mid-line in front of a condition: the query still runs, quietly returns more rows than you wanted, and nothing in the result announces that a filter went missing, so either say in the comment when the disabled line comes back or delete it.
CREATE TABLE ticket (
id INTEGER PRIMARY KEY,
status TEXT,
priority INTEGER,
minutes_open INTEGER
);
INSERT INTO ticket (id, status, priority, minutes_open) VALUES
(1, 'open', 1, 20),
(2, 'open', 3, 400),
(3, 'closed', 1, 900),
(4, 'open', 1, 240),
(5, 'open', 2, 95);
-- Feeds the on-call pager screen; runs every 60 seconds.
-- Priority 1 only: ops wants to be woken for outages, not for
-- routine requests (runbook OPS-114).
SELECT id, minutes_open
FROM ticket
WHERE status = 'open'
AND priority = 1
/* 15 is the SLA warning threshold, not a guess.
If the SLA moves, this number moves with it. */
AND minutes_open > 15;A comment should carry the fact from outside the database that made a filter necessary, because the SQL text already states what the filter does.
Worked examples
Disabling one condition on purpose
Shows why AND at the start of a line makes a predicate safe to comment out, and how the disabled line records its own return date.
CREATE TABLE reading (id INTEGER, sensor TEXT, celsius REAL);
INSERT INTO reading VALUES
(1, 'lab-a', 21.5),
(2, 'lab-a', 78.0),
(3, 'lab-b', 22.1),
(4, 'lab-b', -41.0);
-- -41 C readings come from probes that fell out of the socket, and
-- 78 C is the heater test rig. Both are real rows we must not delete,
-- so the sane-range guard lives in the query instead.
SELECT id, sensor, celsius
FROM reading
WHERE celsius > -20
AND celsius < 60
-- AND sensor = 'lab-a' put back once lab-b is recalibrated (ticket 88)
;Example explained
Line 1The three lines above SELECT name the two junk values by number, so the next reader knows -41 and 78 are equipment artifacts rather than data.
Line 2Because AND begins its own line, the sensor test could be switched off by adding -- to exactly one line and nothing else moved.
Line 3The disabled line states the condition for re-enabling it, which is what separates a note from abandoned code.
Line 4The semicolon sits alone on the last line, so the statement stays complete however many trailing predicate lines are commented out.
A header block that says what not to change
Uses a multi-line /* ... */ block for provenance and an inline block comment that closes mid-line so parsing continues.
CREATE TABLE payment (id INTEGER, status TEXT, cents INTEGER);
INSERT INTO payment VALUES
(1, 'settled', 500),
(2, 'settled', 12000),
(3, 'pending', 30000);
/* Refund-eligibility list, requested by finance on 2026-03-02.
There is deliberately no minimum amount: they refund 5-cent
payments too, so do not tidy this up by adding cents >= 1000. */
SELECT id, cents /* whole cents, so money never rounds */
FROM payment
WHERE status = 'settled'; -- a pending payment holds no money to return yetExample explained
Line 1The /* ... */ header spans three lines and sits before SELECT, where no clause has begun, so it belongs to the statement as a whole.
Line 2The inline /* whole cents ... */ closes on the same line, which is why FROM on the next line is still read as part of the query.
Line 3The trailing -- explains why 'settled' is the right value, instead of translating the = operator into English.
Line 4Row 3 is missing because its status is 'pending', and the comment records why that exclusion is correct rather than restating it.
Important notes
MySQL treats -- as a comment only when a space or control character follows it, so -- with the space is the habit to keep; MySQL also executes /*! ... */ hint comments instead of ignoring them.
Comments travel with the statement: a CREATE VIEW body keeps them and query logs echo them, so keep credentials and customer data out. Block comments nest in PostgreSQL but not in SQLite or MySQL.
Common mistakes
Writing -- filters for open tickets above WHERE status = 'open': it repeats the code, goes stale at the first edit, and trains readers to skip your comments entirely.
Commenting out the final condition while AND sits at the end of the previous line, which leaves a dangling AND before the semicolon and a syntax error instead of a result.
Dropping -- mid-line in front of a condition, as in WHERE paid = 1 -- AND cents > 100: no error appears, just a wider result set that survives review.
Try it yourself
Change, predict, then run
Paste the ticket query into the editor, change 15 to 60, and rewrite the block comment so it names the rule the new number comes from. Then comment out the AND priority = 1 line and confirm you get 3 rows instead of 1, with no syntax error.
Open the SQL workspaceCheck your understanding
Two people disable the priority test for a quick check. One writes it as a trailing comment on the previous line (WHERE status = 'open' -- AND priority = 1) and the other puts it on its own commented line in a leading-AND layout. Why is the first version the more dangerous habit?
- It raises a syntax error at the semicolon, so the check cannot run at all.
- It changes nothing, because -- hides text from people while the parser still applies the condition.
- It still parses, so the query quietly returns more rows and the edit can be committed unnoticed.
- Trailing comments are ignored inside WHERE but still applied inside the SELECT list.
Show answer
Both forms remove the condition, but the mid-line version leaves a perfectly valid query with a weaker filter, so the only symptom is extra rows that nobody flags. Option 0 is tempting because a dangling AND really does produce a syntax error, but that happens when AND ends the previous line, and it is the safer failure precisely because it stops you.