1
0
Fork 0
mirror of https://github.com/treffynnon/sqlstyle.guide.git synced 2025-03-09 12:49:51 -05:00

Update sqlstyle.guide.md

initial update for my taste and SQL Server
This commit is contained in:
Wes Brown 2017-01-04 16:53:52 -06:00 committed by GitHub
parent 89421d340e
commit 981e802e86

View file

@ -16,7 +16,7 @@ It is easy to include this guide in [Markdown format][dl-md] as a part of a
project's code base or reference it here for anyone on the project to freely project's code base or reference it here for anyone on the project to freely
read—much harder with a physical book. read—much harder with a physical book.
SQL style guide by [Simon Holywell][simon] is licensed under a [Creative Commons The origional SQL style guide by [Simon Holywell][simon] is licensed under a [Creative Commons
Attribution-ShareAlike 4.0 International License][licence]. Attribution-ShareAlike 4.0 International License][licence].
Based on a work at [http://www.sqlstyle.guide][self]. Based on a work at [http://www.sqlstyle.guide][self].
@ -28,8 +28,6 @@ Based on a work at [http://www.sqlstyle.guide][self].
* Make judicious use of white space and indentation to make code easier to read. * Make judicious use of white space and indentation to make code easier to read.
* Store [ISO-8601][iso-8601] compliant time and date information * Store [ISO-8601][iso-8601] compliant time and date information
(`YYYY-MM-DD HH:MM:SS.SSSSS`). (`YYYY-MM-DD HH:MM:SS.SSSSS`).
* Try to use only standard SQL functions instead of vendor specific functions for
reasons of portability.
* Keep code succinct and devoid of redundant SQL—such as unnecessary quoting or * Keep code succinct and devoid of redundant SQL—such as unnecessary quoting or
parentheses or `WHERE` clauses that can otherwise be derived. parentheses or `WHERE` clauses that can otherwise be derived.
* Include comments in SQL code where necessary. Use the C style opening `/*` and * Include comments in SQL code where necessary. Use the C style opening `/*` and
@ -37,16 +35,22 @@ Based on a work at [http://www.sqlstyle.guide][self].
them with a new line. them with a new line.
```sql ```sql
SELECT file_hash -- stored ssdeep hash SELECT
FROM file_system file_hash -- stored ssdeep hash
WHERE file_name = '.vimrc'; FROM
file_system
WHERE
file_name = '.vimrc';
``` ```
```sql ```sql
/* Updating the file record after writing to the file */ /* Updating the file record after writing to the file */
UPDATE file_system UPDATE
SET file_modified_date = '1980-02-22 13:19:01.00000', file_system
SET
file_modified_date = '1980-02-22 13:19:01.00000',
file_size = 209732 file_size = 209732
WHERE file_name = '.vimrc'; WHERE
file_name = '.vimrc';
``` ```
### Avoid ### Avoid
@ -55,9 +59,7 @@ UPDATE file_system
* Descriptive prefixes or Hungarian notation such as `sp_` or `tbl`. * Descriptive prefixes or Hungarian notation such as `sp_` or `tbl`.
* Plurals—use the more natural collective term where possible instead. For example * Plurals—use the more natural collective term where possible instead. For example
`staff` instead of `employees` or `people` instead of `individuals`. `staff` instead of `employees` or `people` instead of `individuals`.
* Quoted identifiers—if you must use them then stick to SQL92 double quotes for * Quoted identifiers—if you must use them then stick to SQL Server's [] instead of SET QUOTED_IDENTIFIER ON to escape reserved words or words with invalid characters in them.
portability (you may need to configure your SQL server to support this depending
on vendor).
* Object oriented design principles should not be applied to SQL or database * Object oriented design principles should not be applied to SQL or database
structures. structures.
@ -78,8 +80,10 @@ UPDATE file_system
understood. understood.
```sql ```sql
SELECT first_name SELECT
FROM staff; first_name
FROM
staff;
``` ```
### Tables ### Tables
@ -110,14 +114,20 @@ SELECT first_name
a column defined in the schema. a column defined in the schema.
```sql ```sql
SELECT first_name AS fn SELECT
FROM staff AS s1 first_name AS fn
JOIN students AS s2 FROM
ON s2.mentor_id = s1.staff_num; staff AS s1
INNER JOIN
students AS s2
ON
s2.mentor_id = s1.staff_num;
``` ```
```sql ```sql
SELECT SUM(s.monitor_tally) AS monitor_total SELECT
FROM staff AS s; SUM(s.monitor_tally) AS monitor_total
FROM
staff AS s;
``` ```
### Stored procedures ### Stored procedures
@ -154,13 +164,33 @@ like `SELECT` and `WHERE`.
It is best to avoid the abbreviated keywords and use the full length ones where It is best to avoid the abbreviated keywords and use the full length ones where
available (prefer `ABSOLUTE` to `ABS`). available (prefer `ABSOLUTE` to `ABS`).
Do not use database server specific keywords where an ANSI SQL keyword already Do not user SQL ANSI 89 syntax anywhere even if the resulting query returns the
exists performing the same function. This helps to make code more portable. same results to cut down on confusion and keep the code intent clear
```sql ```sql
SELECT model_num SELECT
FROM phones AS p a.person_id,
WHERE p.release_date > '2014-09-30'; b.address_id,
b.address_1
FROM
person a, address b
where
a.person_id = b.address_id
```
Instead favor SQL ANSI 92
```sql
SELECT
a.person_id,
b.address_id,
b.address_1
FROM
person a
INNER JOIN
address b
on
a.person_id = b.address_id
``` ```
### White space ### White space
@ -170,21 +200,23 @@ spacing is used. Do not crowd code or remove natural language spaces.
#### Spaces #### Spaces
Spaces should be used to line up the code so that the root keywords all end on Spaces should be used to line up the code so that the root keywords all start on
the same character boundary. This forms a river down the middle making it easy for the same character boundary.
the readers eye to scan over the code and separate the keywords from the
implementation detail. Rivers are [bad in typography][rivers], but helpful here.
```sql ```sql
SELECT f.average_height, f.average_diameter SELECT
FROM flora AS f f.average_height, f.average_diameter
WHERE f.species_name = 'Banksia' FROM
OR f.species_name = 'Sheoak' flora AS f
OR f.species_name = 'Wattle'; WHERE
f.species_name = 'Banksia'
OR
f.species_name = 'Sheoak'
OR
f.species_name = 'Wattle';
``` ```
Notice that `SELECT`, `FROM`, etc. are all right aligned while the actual column Notice that `SELECT`, `FROM`, etc. are all left aligned and are on their own line.
names and implementation specific details are left aligned.
Although not exhaustive always include spaces: Although not exhaustive always include spaces:
@ -194,10 +226,16 @@ Although not exhaustive always include spaces:
comma or semicolon. comma or semicolon.
```sql ```sql
SELECT a.title, a.release_date, a.recording_date SELECT
FROM albums AS a a.title,
WHERE a.title = 'Charcoal Lane' a.release_date,
OR a.title = 'The New Danger'; a.recording_date
FROM
albums AS a
WHERE
a.title = 'Charcoal Lane'
OR
a.title = 'The New Danger';
``` ```
#### Line spacing #### Line spacing
@ -216,23 +254,32 @@ creates a uniform gap down the middle of query. It makes it much easier to scan
the query definition over quickly too. the query definition over quickly too.
```sql ```sql
INSERT INTO albums (title, release_date, recording_date) INSERT INTO
VALUES ('Charcoal Lane', '1990-01-01 01:01:01.00000', '1990-01-01 01:01:01.00000'), albums (title, release_date, recording_date)
VALUES
('Charcoal Lane', '1990-01-01 01:01:01.00000', '1990-01-01 01:01:01.00000'),
('The New Danger', '2008-01-01 01:01:01.00000', '1990-01-01 01:01:01.00000'); ('The New Danger', '2008-01-01 01:01:01.00000', '1990-01-01 01:01:01.00000');
``` ```
```sql ```sql
UPDATE albums UPDATE
SET release_date = '1990-01-01 01:01:01.00000' albums
WHERE title = 'The New Danger'; SET
release_date = '1990-01-01 01:01:01.00000'
WHERE
title = 'The New Danger';
``` ```
```sql ```sql
SELECT a.title, SELECT
a.title,
a.release_date, a.recording_date, a.production_date -- grouped dates together a.release_date, a.recording_date, a.production_date -- grouped dates together
FROM albums AS a FROM
WHERE a.title = 'Charcoal Lane' albums AS a
OR a.title = 'The New Danger'; WHERE
a.title = 'Charcoal Lane'
OR
a.title = 'The New Danger';
``` ```
### Indentation ### Indentation
@ -242,40 +289,58 @@ are followed.
#### Joins #### Joins
Joins should be indented to the other side of the river and grouped with a new Joins should follow the same indentation as normal.
line where necessary. Again, fully expand key words prefer INNER JOIN over JOIN.
```sql ```sql
SELECT r.last_name SELECT
FROM riders AS r r.last_name
INNER JOIN bikes AS b FROM
ON r.bike_vin_num = b.vin_num riders AS r
AND b.engines > 2 INNER JOIN
bikes AS b
INNER JOIN crew AS c ON
ON r.crew_chief_last_name = c.last_name r.bike_vin_num = b.vin_num
AND c.chief = 'Y'; AND
b.engines > 2
INNER JOIN
crew AS c
ON
r.crew_chief_last_name = c.last_name
AND
c.chief = 'Y';
``` ```
#### Subqueries #### Subqueries
Subqueries should also be aligned to the right side of the river and then laid Subqueries should follow the same alignment rules with the query beginning on the line after the open parenthesis.
out using the same style as any other query. Sometimes it will make sense to have
the closing parenthesis on a new line at the same character position as it's
opening partner—this is especially true where you have nested subqueries.
```sql ```sql
SELECT r.last_name, SELECT
(SELECT MAX(YEAR(championship_date)) r.last_name,
FROM champions AS c (
WHERE c.last_name = r.last_name SELECT
AND c.confirmed = 'Y') AS last_championship_year MAX(YEAR(championship_date))
FROM riders AS r FROM
WHERE r.last_name IN champions AS c
(SELECT c.last_name WHERE
FROM champions AS c c.last_name = r.last_name
WHERE YEAR(championship_date) > '2008' AND
AND c.confirmed = 'Y'); c.confirmed = 'Y'
) AS last_championship_year
FROM
riders AS r
WHERE
r.last_name IN
(
SELECT
c.last_name
FROM
champions AS c
WHERE
YEAR(championship_date) > '2008'
AND
c.confirmed = 'Y'
);
``` ```
### Preferred formalisms ### Preferred formalisms
@ -290,14 +355,19 @@ SELECT r.last_name,
likely should be. likely should be.
```sql ```sql
SELECT CASE postcode SELECT
CASE postcode
WHEN 'BN1' THEN 'Brighton' WHEN 'BN1' THEN 'Brighton'
WHEN 'EH1' THEN 'Edinburgh' WHEN 'EH1' THEN 'Edinburgh'
END AS city END AS city
FROM office_locations FROM
WHERE country = 'United Kingdom' office_locations
AND opening_time BETWEEN 8 AND 9 WHERE
AND postcode IN ('EH1', 'BN1', 'NN1', 'KW1') country = 'United Kingdom'
AND
opening_time BETWEEN 8 AND 9
AND
postcode IN ('EH1', 'BN1', 'NN1', 'KW1')
``` ```
## Create syntax ## Create syntax
@ -310,8 +380,6 @@ Indent column definitions by four (4) spaces within the `CREATE` definition.
### Choosing data types ### Choosing data types
* Where possible do not use vendor specific data types—these are not portable and
may not be available in older versions of the same vendor's software.
* Only use `REAL` or `FLOAT` types where it is strictly necessary for floating * Only use `REAL` or `FLOAT` types where it is strictly necessary for floating
point mathematics otherwise prefer `NUMERIC` and `DECIMAL` at all times. Floating point mathematics otherwise prefer `NUMERIC` and `DECIMAL` at all times. Floating
point rounding errors are a nuisance! point rounding errors are a nuisance!
@ -354,6 +422,7 @@ constraints along with field value validation.
##### General ##### General
* Tables must have at least one key to be complete and useful. * Tables must have at least one key to be complete and useful.
* This key should be made the clustered index unless there is a more suitable candidate.
* Constraints should be given a custom name excepting `UNIQUE`, `PRIMARY KEY` * Constraints should be given a custom name excepting `UNIQUE`, `PRIMARY KEY`
and `FOREIGN KEY` where the database vendor will generally supply sufficiently and `FOREIGN KEY` where the database vendor will generally supply sufficiently
intelligible names automatically. intelligible names automatically.
@ -411,13 +480,15 @@ CREATE TABLE staff (
concerns such as time-based archiving or location in a multi-national concerns such as time-based archiving or location in a multi-national
organisation. Later queries must then work across multiple tables with `UNION` organisation. Later queries must then work across multiple tables with `UNION`
rather than just simply querying one table. rather than just simply querying one table.
Prefer table partitioning if possible.
## Appendix ## Appendix
### Reserved keyword reference ### Reserved keyword reference
A list of ANSI SQL (92, 99 and 2003), MySQL 3 to 5.x, PostgreSQL 8.1, MS SQL Server 2000, MS ODBC and Oracle 10.2 reserved keywords. A list of SQL Server 2008 and above reserved keywords.
[Reserved Keywords] [sql-server-reserved-keywords]
```sql ```sql
A A
@ -1209,65 +1280,214 @@ UTC_DATE
UTC_TIME UTC_TIME
UTC_TIMESTAMP UTC_TIMESTAMP
VACUUM VACUUM
VALID ADD
VALIDATE ALL
VALIDATOR ALTER
VALUE AND
ANY
AS
ASC
AUTHORIZATION
BACKUP
BEGIN
BETWEEN
BREAK
BROWSE
BULK
BY
CASCADE
CASE
CHECK
CHECKPOINT
CLOSE
CLUSTERED
COALESCE
COLLATE
COLUMN
COMMIT
COMPUTE
CONSTRAINT
CONTAINS
CONTAINSTABLE
CONTINUE
CONVERT
CREATE
CROSS
CURRENT
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_USER
CURSOR
DATABASE
DBCC
DEALLOCATE
DECLARE
DEFAULT
DELETE
DENY
DESC
DISK
DISTINCT
DISTRIBUTED
DOUBLE
DROP
DUMP
ELSE
END
ERRLVL
ESCAPE
EXCEPT
EXEC
EXECUTE
EXISTS
EXIT
EXTERNAL
FETCH
FILE
FILLFACTOR
FOR
FOREIGN
FREETEXT
FREETEXTTABLE
FROM
FULL
FUNCTION
GOTO
GRANT
GROUP
HAVING
HOLDLOCK
IDENTITY
IDENTITY_INSERT
IDENTITYCOL
IF
IN
INDEX
INNER
INSERT
INTERSECT
INTO
IS
JOIN
KEY
KILL
LEFT
LIKE
LINENO
LOAD
MERGE
NATIONAL
NOCHECK
NONCLUSTERED
NOT
NULL
NULLIF
OF
OFF
OFFSETS
ON
OPEN
OPENDATASOURCE
OPENQUERY
OPENROWSET
OPENXML
OPTION
OR
ORDER
OUTER
OVER
PERCENT
PIVOT
PLAN
PRECISION
PRIMARY
PRINT
PROC
PROCEDURE
PUBLIC
RAISERROR
READ
READTEXT
RECONFIGURE
REFERENCES
REPLICATION
RESTORE
RESTRICT
RETURN
REVERT
REVOKE
RIGHT
ROLLBACK
ROWCOUNT
ROWGUIDCOL
RULE
SAVE
SCHEMA
SECURITYAUDIT
SELECT
SEMANTICKEYPHRASETABLE
SEMANTICSIMILARITYDETAILSTABLE
SEMANTICSIMILARITYTABLE
SESSION_USER
SET
SETUSER
SHUTDOWN
SOME
STATISTICS
SYSTEM_USER
TABLE
TABLESAMPLE
TEXTSIZE
THEN
TO
TOP
TRAN
TRANSACTION
TRIGGER
TRUNCATE
TRY_CONVERT
TSEQUAL
UNION
UNIQUE
UNPIVOT
UPDATE
UPDATETEXT
USE
USER
VALUES VALUES
VAR_POP
VAR_SAMP
VARBINARY
VARCHAR
VARCHAR2
VARCHARACTER
VARIABLE
VARIABLES
VARYING VARYING
VERBOSE
VIEW VIEW
VOLATILE
WAITFOR WAITFOR
WHEN WHEN
WHENEVER
WHERE WHERE
WHILE WHILE
WIDTH_BUCKET
WINDOW
WITH WITH
WITHIN WITHIN GROUP
WITHOUT
WORK
WRITE
WRITETEXT WRITETEXT
X509
XOR
YEAR
YEAR_MONTH
ZEROFILL
ZONE
``` ```
[simon]: https://www.simonholywell.com/?utm_source=sqlstyle.guide&utm_medium=link&utm_campaign=md-document [simon]: https://www.simonholywell.com/?utm_source=sqlstyle.guide&utm_medium=link&utm_campaign=md-document
"SimonHolywell.com" "SimonHolywell.com"
[issue]: https://github.com/treffynnon/sqlstyle.guide/issues [issue]: https://github.com/SQLServerIO/sqlstyle.guide/issues
"SQL style guide issues on GitHub" "SQL Server style guide issues on GitHub"
[fork]: https://github.com/treffynnon/sqlstyle.guide/fork [fork]: https://github.com/SQLServerIO/sqlstyle.guide/fork
"Fork SQL style guide on GitHub" "Fork SQL Server style guide on GitHub"
[pull]: https://github.com/treffynnon/sqlstyle.guide/pulls/ [pull]: https://github.com/SQLServerIO/sqlstyle.guide/pulls/
"SQL style guide pull requests on GitHub" "SQL Server style guide pull requests on GitHub"
[celko]: https://www.amazon.com/gp/product/0120887975/ref=as_li_ss_tl?ie=UTF8&linkCode=ll1&tag=treffynnon-20&linkId=9c88eac8cd420e979675c815771313d5 [celko]: https://www.amazon.com/gp/product/0120887975/ref=as_li_ss_tl?ie=UTF8&linkCode=ll1&tag=treffynnon-20&linkId=9c88eac8cd420e979675c815771313d5
"Joe Celko's SQL Programming Style (The Morgan Kaufmann Series in Data Management Systems)" "Joe Celko's SQL Programming Style (The Morgan Kaufmann Series in Data Management Systems)"
[dl-md]: https://raw.githubusercontent.com/treffynnon/sqlstyle.guide/gh-pages/_includes/sqlstyle.guide.md [dl-md]: https://raw.githubusercontent.com/SQLServerIO/sqlstyle.guide/gh-pages/_includes/sqlstyle.guide.md
"Download the guide in Markdown format" "Download the guide in Markdown format"
[iso-8601]: https://en.wikipedia.org/wiki/ISO_8601 [iso-8601]: https://en.wikipedia.org/wiki/ISO_8601
"Wikipedia: ISO 8601" "Wikipedia: ISO 8601"
[rivers]: http://practicaltypography.com/one-space-between-sentences.html
"Practical Typography: one space between sentences"
[reserved-keywords]: #reserved-keyword-reference [reserved-keywords]: #reserved-keyword-reference
"Reserved keyword reference" "Reserved keyword reference"
[sql-server-reserved-keywords] https://msdn.microsoft.com/en-us/library/ms189822.aspx
"Microsoft: SQL Server keyword reference"
[eav]: https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model [eav]: https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model
"Wikipedia: Entityattributevalue model" "Wikipedia: Entityattributevalue model"
[self]: http://www.sqlstyle.guide [self]: https://sqlserverio.github.com/sqlstyle.guide
"SQL style guide by Simon Holywell" "SQL Server style guide by Wes Brown"
[licence]: http://creativecommons.org/licenses/by-sa/4.0/ [licence]: http://creativecommons.org/licenses/by-sa/4.0/
"Creative Commons Attribution-ShareAlike 4.0 International License" "Creative Commons Attribution-ShareAlike 4.0 International License"