SQL / RELATIONAL FOUNDATIONS
Statements, clauses, keywords, and semicolons
You can break a SQL statement into its clauses, reformat it freely without changing its meaning, and use semicolons to mark where each statement ends.
What you will learn
- Split any query into clauses by finding the keyword that opens each one
- Reformat a statement across lines or change keyword case without changing results
- End every statement with a semicolon so a multi-statement script parses
- Tell a literal ('Earth') apart from a quoted identifier ("order") and from a keyword
Understanding Statements, clauses, keywords, and semicolons
A statement is the whole unit the server compiles and runs: everything from the first keyword up to the semicolon. Inside it, a clause is one functional part -- SELECT names the output columns, FROM names the source, WHERE filters rows -- and each clause begins with a keyword that acts as a landmark for the parser. Because the parser finds clauses by those landmark words and expects them in a fixed order, it can tell where one clause stops and the next begins with no punctuation between them. That is also why a misplaced keyword kills the whole statement instead of just one clause: the parser loses its place in the grammar and abandons everything it was reading.
Outside quoted text, SQL treats any run of spaces, tabs, and newlines as a single token separator, and it folds unquoted words to one case before matching them against keywords, so select, SELECT, and SeLeCt are the same token. That freedom has a cost: a line break cannot mean "statement finished", because a line break means nothing at all. The semicolon carries that meaning instead, which is why a client either sits waiting for more input or reports an error on the next statement's first keyword when you leave one out.
Keywords are reserved, and the parser matches them before it ever considers that a word might be your table or column name, so SELECT order FROM sale fails because order is read as the beginning of ORDER BY. Quoting removes the ambiguity, but the two kinds of quotes mean different things: single quotes hold a string literal, which is data, while double quotes hold an identifier, which is a name. WHERE city = "Lisbon" therefore asks the engine to compare one column against another column called Lisbon, which is why strict engines answer with a complaint about a missing column rather than returning zero rows.
CREATE TABLE planet (name TEXT, moons INTEGER);
INSERT INTO planet (name, moons)
VALUES ('Mercury', 0), ('Earth', 1), ('Mars', 2), ('Jupiter', 95);
SELECT name, moons FROM planet WHERE moons > 0 ORDER BY moons DESC;
select name,
moons
from planet
WHERE moons > 0
ORDER by moons desc;A statement is a fixed sequence of keyword-introduced clauses ended by a semicolon, and layout and keyword case are free precisely because those two things carry all the structure.
Worked examples
Clause order is part of the grammar
Correctly spelled clauses still fail when they appear in the wrong position.
SELECT name FROM planet ORDER BY moons WHERE moons > 0;Example explained
Line 1Every clause here is written correctly; only the order is wrong.
Line 2The grammar puts ORDER BY at the end of a SELECT, so once it is matched there is no legal position left for WHERE.
Line 3The caret marks the first token that could not be matched, not the thing that is missing.
Line 4Nothing at all runs, because a statement is compiled as one unit.
A missing semicolon merges two statements
Shows that the parser keeps reading past a line break until it finds a terminator.
SELECT name FROM planet
SELECT moons FROM planet;Example explained
Line 1Line 1 looks finished to a reader, but it has no terminator, so the parser carries on.
Line 2After planet the grammar allows WHERE, GROUP BY, ORDER BY and a few others, but never SELECT, so the second keyword is where it breaks.
Line 3The fix belongs at the end of line 1, even though the error is reported on line 2.
Comments and layout are invisible to the engine
One statement spread over six lines with both comment styles inside it.
SELECT
name, -- the parser stops reading this line at the two dashes
moons /* a block comment can sit inside a clause */
FROM planet
WHERE moons BETWEEN 1 AND 3
ORDER BY name;Example explained
Line 1-- removes the rest of that physical line, so never put it before something the clause still needs.
Line 2/* ... */ is stripped and replaced by a token separator, which is why it can appear in the middle of a column list.
Line 3Six lines still form one statement, because only the semicolon ends it.
Line 4BETWEEN is inclusive, so Earth (1) and Mars (2) qualify while Mercury (0) and Jupiter (95) do not.
Important notes
Most clients accept a single statement with no trailing semicolon, so it feels optional right up to the moment you send two statements together; type it every time.
To use a reserved word as a name, quote it: "order" in standard SQL and Postgres, `order` in MySQL, [order] in SQL Server. In Postgres a quoted identifier keeps its exact case, so "Order" and order are two different names.
Common mistakes
Ordering clauses the way you think about them, as in SELECT ... ORDER BY ... WHERE ...; the parser rejects the entire statement at WHERE even though every clause is spelled correctly.
Using double quotes for a text value: WHERE name = "Earth" is read as a column reference in Postgres and fails with column "Earth" does not exist, while MySQL and SQLite quietly treat it as text, so the same script behaves differently per engine.
Omitting the semicolon between statements in a script; the next statement gets swallowed into the previous one, so the error points at a line that looks perfectly fine, and an interactive client just keeps waiting for more input.
Try it yourself
Change, predict, then run
Create the planet table in the editor, then write the same query twice: once with every clause on its own line in lower case, once crammed onto a single line in upper case, and confirm the rows match. Now delete the semicolon between them and note which line the engine blames.
Open the SQL workspaceCheck your understanding
A script holds two SELECT statements and the first one has no semicolon after it. The engine reports a syntax error at the word SELECT on line 2. What explains that?
- A newline ends a statement in SQL, so the second SELECT arrived as an incomplete fragment.
- SELECT may appear only once per script unless the statements are split into separate files.
- Newlines are only token separators, so with no semicolon the parser is still inside the first statement and meets SELECT where no clause keyword may start.
- The first statement is fine, and the client simply sent the two statements in the wrong order.
Show answer
The semicolon is the only statement terminator, so after planet the parser keeps consuming tokens and finds SELECT in a position where its grammar allows only a clause keyword such as WHERE or ORDER BY; the complaint lands on line 2 although the omission is at the end of line 1. The first option is tempting because Python and shell really do end a statement at a newline, but SQL ignores newlines completely outside quoted text.