31
SQL Patterns in Practice (You’re Probably Doing it Wrong) Sean Scott, Oracle DBA [email protected]

SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Embed Size (px)

DESCRIPTION

Despite being "Structured" Query Language, there's not much structure required to write SQL. However, poorly formatted SQL makes debugging and editing more time consuming and inefficient than it needs to be. Bad examples of SQL abound and have found their way into the mainstream as practitioners adopt the methods they find on popular web sites and blogs into their own repertoire. This presentation is appropriate for anyone who uses SQL, no matter how seasoned. It introduces pragmatic design patterns for writing SQL that make it easier (and more enjoyable) to understand and edit. Based on over 25 years of applied experience with SQL as a primary programming language, these techniques are are relevant to any implementation of SQL, including Oracle, MySQL, SQL Server and PostgreSQL.

Citation preview

Page 1: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SQL Patterns in Practice(You’re Probably Doing it Wrong)

Sean Scott, Oracle [email protected]

Page 2: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

The Four Rules of Writing SQL

To improve readability and self-document code, follow these four simple rules.

Page 3: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT order.order_id, order_line, product_name, unit_price, supplier_name, SUM(total_units), sum(unit_price*total_units)FROM order, product, order_items WHERE ((order_items.product_id = product.product_id) and ((order.order_id = order_items.order_id) and (customer_id = 42)))GROUP BY order_id, product_name, unit_price, supplier_name, total_unitsORDER BY order_id, product_name;

Page 4: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Rule 1Everything on its own line

This improves readability and makes troubleshooting easier.

Page 5: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT order.order_id,order_line,product_name,unit_price,supplier_name,SUM(total_units), sum(unit_price*total_units)FROM order,product,order_items WHERE ((order_items.product_id = product.product_id) and((order.order_id = order_items.order_id) and(customer_id = 42)))GROUP BY…

Page 6: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT order.order_id,--order_line,product_name,--unit_price,supplier_name--,--SUM(total_units), --sum(unit_price*total_units)FROM order,product--,--order_items WHERE ((order_items.product_id = product.product_id) and(--(order.order_id = order_items.order_id) andand (customer_id = 42)))

Page 7: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Rule 2Put commas, ANDs at the beginning of lines, not the

endThis minimizes commenting necessary to remove

something from your query.

Page 8: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT order.order_id, order_line, product_name, unit_price, supplier_name, SUM(total_units), sum(unit_price*total_units)FROM order, product, order_items WHERE ((order_items.product_id = product.product_id) and ((order.order_id = order_items.order_id) and (customer_id = 42)))

Page 9: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT order.order_id--, order_line, product_name--, unit_price, supplier_name--, SUM(total_units)--, sum(unit_price*total_units)FROM order, product--, order_items WHERE ((order_items.product_id = product.product_id)--and ((order.order_id = order_items.order_id) ( and (customer_id = 42)))

Page 10: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Rule 3When joining tables, use short, meaningful aliases

for tables and always prefix columns

It eliminates confusion about what table a column belongs to, and improves readability.

Page 11: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, ol.order_line, p.product_name, ol.unit_price, p.supplier_name, SUM(ol.total_units), sum(p.unit_price*ol.total_units)FROM order o, product p, order_items oiWHERE ((oi.product_id = p.product_id) and ((o.order_id = oi.order_id) and (o.customer_id = 42)))

Page 12: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Rule 4Avoid parentheses in

WHERE clauses unless required to nest “OR”

expressionsSimplify SQL by eliminating that which is unnecessary

Page 13: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, ol.order_line, p.product_name, ol.unit_price, p.supplier_name, SUM(ol.total_units), sum(p.unit_price*ol.total_units)FROM order o, product p, order_items oiWHERE oi.product_id = p.product_id and o.order_id = oi.order_id and o.customer_id = 42

Page 14: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Four Rules• Everything on its own line• Put commas, “AND” at the beginning of lines, not

the end• When joining tables, use short, meaningful

aliases for tables and always prefix columns• Avoid parentheses in WHERE clauses unless

required to nest “OR” expressions.

Page 15: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

The Six Habits of Legible SQL

Seven habits to adopt when writing SQL that will improve legibility

Page 16: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, ol.order_line, p.product_name, ol.unit_price, p.supplier_name, SUM(ol.total_units), sum(p.unit_price*ol.total_units)FROM order o, product p, order_items oiWHERE oi.product_id = p.product_id and o.order_id = oi.order_id and o.customer_id = 42

Page 17: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Pick a case and stick to it

Upper or lower, it doesn’t matter, provided you’re consistent. Case provides visual cues about the purpose or

meaning of the various parts of your statement.

Page 18: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, ol.order_line, p.product_name, ol.unit_price, p.supplier_name, SUM(ol.total_units), SUM(p.unit_price*ol.total_units)FROM order o, product p, order_items oiWHERE oi.product_id = p.product_id and o.order_id = oi.order_id and o.customer_id = 42

Page 19: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Use white space to align statements for

meaningWhite space makes the parts and purpose of a statement

more visually apparent and easier to read.

Page 20: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, ol.order_line, p.product_name, ol.unit_price, p.supplier_name, SUM(ol.total_units), SUM(p.unit_price*ol.total_units) FROM order o, product p, order_items oi WHERE oi.product_id = p.product_id AND o.order_id = oi.order_id AND o.customer_id = 42GROUP BY o.order_id, ol.order_line...

Page 21: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, ol.order_line, p.product_name, ol.unit_price, p.supplier_name, SUM(ol.total_units), SUM(p.unit_price*ol.total_units)FROM order o, product p, order_items oiWHERE oi.product_id = p.product_idAND o.order_id = oi.order_idAND o.customer_id = 42GROUP BY o.order_id, ol.order_line...

Page 22: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Use white space to align operands and

aliasesWhen all operands fall into alignment, it’s much easier to see

the left and right sides in the WHERE statement. Likewise, when table aliases are aligned it’s much easier to reference them.

Page 23: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, ol.order_line, p.product_name, ol.unit_price, p.supplier_name, SUM(ol.total_units), SUM(p.unit_price*ol.total_units) FROM order o, product p, order_items oi WHERE oi.product_id = p.product_id AND o.order_id = oi.order_id AND o.customer_id = 42GROUP BY o.order_id, ol.order_line...

Page 24: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Group columns by tableIf you need to troubleshoot by commenting out a table, it’s

more efficient when everything is together.

Page 25: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, p.product_name, p.supplier_name, ol.order_line, ol.unit_price, SUM(ol.total_units), SUM(p.unit_price*ol.total_units) FROM order o, product p, order_items oi WHERE oi.product_id = p.product_id AND o.order_id = oi.order_id AND o.customer_id = 42GROUP BY o.order_id, ol.order_line...

Page 26: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

In a WHERE clause, equalities first, then IN

lists, and subqueries last.

This orders statements from the least to most likely to cause a problem and need to be edited.

Page 27: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, p.product_name, p.supplier_name, ol.order_line, ol.unit_price, SUM(ol.total_units), SUM(p.unit_price*ol.total_units) FROM order o, product p, order_items oi WHERE oi.product_id = p.product_id AND o.order_id = oi.order_id AND o.customer_id = 42GROUP BY o.order_id, ol.order_line...

Page 28: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, p.product_name, p.supplier_name, ol.order_line, ol.unit_price, SUM(ol.total_units), SUM(p.unit_price*ol.total_units) FROM order o INNER JOIN order_items oi ON o.order_id = oi.order_id INNER JOIN product p ON oi.product_id = p.product_id WHERE o.customer_id = 42GROUP BY o.order_id, ol.order_line...

Page 29: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Place aggregate functions last in the

SELECTIt makes the GROUP BY easier to write—just copy/paste the

SELECT clause up to the aggregates as the GROUP BY.

Page 30: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

SELECT o.order_id, p.product_name, p.supplier_name, ol.order_line, ol.unit_price, SUM(ol.total_units), SUM(p.unit_price*ol.total_units) FROM order o, product p, order_items oi WHERE oi.product_id = p.product_id AND o.order_id = oi.order_id AND o.customer_id = 42GROUP BY o.order_id, ol.order_line...

Page 31: SQL Patterns in Practice - You're (Probably) Doing it Wrong - Methods for Improving SQL

Six Habits of Legible SQL

• Pick a case and stick to it• Use white space to align statements for meaning• Use white space to align operands and aliases• Group columns by table• In a WHERE clause, equalities first, then IN lists,

and subqueries last• Place aggregate functions last in the SELECT