The following is based on practical experience with disparate SQL formatting practices used by hundreds of different development shops within North America and elsewhere. These are intended as guidelines, for use as a starting point in developing a consistent personal style of SQL formatting. Discretion must of course be used for individual cases. Recommended deviations from the presented 'canonical' style have been mentioned where appropriate, but these are by no means exclusive. Adopting these or similar guidelines should greatly improve readability of code and clarity of thought, with a corresponding improvement in productivity. Some small effort has been made to use examples which could conceivably make 'practical sense', but this is by no means guaranteed, as contrived examples often do a better job of illustrating the formatting. This remains a work in progress so constructive criticism is welcomed.

How to Format SQL

SQL keywords should be entered in upper case to visually differentiate user-defined identifiers such as table and column names, which should be in lower case or mixed case.

Each clause starts a new line.

SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY

When there is only one 'argument' to a clause, it goes on the same line as the clause keyword.

SELECT <single_expression>
FROM single_table
WHERE <single_predicate>
GROUP BY single_column
HAVING <single_predicate>
ORDER BY single_column

when there are multiple comma-separated arguments, the arguments are listed one per line beneath the clause keyword, and indented. (two spaces is necessary and sufficient for fixed-width fonts; more spaces may be necessary for variable-width fonts. DO NOT use tabs.) When refering to multiple tables, it is always advisable to use a short form correlation name, usually derived from the initial or initials of the full table name.

SELECT
  <first_expression>,
  <second_expression>,
  <third_expression>
FROM
  first_table t1,
  second_table t2,
  third_table t3
GROUP BY
  c1,
  c2,
  c3
ORDER BY
  c1,
  c2,
  c3

Multiple elements within parentheses should also be indented.

SELECT 
  VALUES (
    10,
    100,
    1000
  )
FROM dummytable
GROUP BY
  c1,
  c2,
  GROUPING SETS (
    (
      c1,
      c2,
      c3
    )
  )

Some sets of elements lend themselves to conceptual grouping; you may choose to place the elements from such a group together on one line.

SELECT
  name_first, name_middle, name_last,
  address_street, address_city, address_state, address_pcode, address_country,
  phone_areacode, phone_number
FROM demographics_table
GROUP BY GROUPING SETS (
  (a, b, c),
  (a, c),
  (b)
)  

JOIN clauses should be laid out each on a new line, with the JOIN keyword beginning the line.

SELECT
  <columns>
FROM
  table_one t1
  LEFT JOIN table_two t2 ON t2.column_A = t1.column_B
  RIGHT JOIN table_three t3 ON t3.column_C = t1.column_D

Subselects should be further indented, with their enclosing parentheses on distinct lines.

SELECT
  (
    SELECT c1
    FROM t1
    WHERE c1='xyz'
  ),
  c2
FROM t2

Where the subselect is small, you may choose to reduce it to a single line.

SELECT
  (SELECT c1 FROM t1 WHERE c1='xyz'),
  c2
FROM t2

Multiple predicates in a WHERE clause should ideally be placed one per line where possible, with the logical conjunction (AND, OR) starting the line, and expressions within parentheses further indented.

SELECT column
FROM table
WHERE
  <predicate_1>
  AND <predicate_2>
  AND (
    <predicate_3>
    OR <predicate_4>
    OR <predicate_5>
  )
Sometimes you may also choose to group some predicates on a single line.
WHERE
  <predicate_1> AND <predicate_2>
  AND (<predicate_3> OR <predicate_4> OR <predicate_5>)

Set operations (UNION, EXCEPT, INTERSECT) between two subselects should be formatted with the set operator keyword on its own line, unindented, between the subselects, as follows:

SELECT c1 FROM t1
UNION
SELECT c2 FROM t2
EXCEPT
SELECT c3 FROM t3

Finally, these and similar ideas can be applied to other standard (and non-standard) SQL statements.

INSERT INTO my_table (
  <columns>
)
<some_table_expression>

UPDATE my_table
SET 
  <assignment_clauses>
WHERE
  <predicates>

DELETE FROM my_table
WHERE
  <predicates>