10 best practices for writing SQL queries for data analysis


Table of Contents

SQL is easily the most common language used for data extraction. According to a 2020 survey, it's used by 80% of data professionals From startups to giants, in tech, everyone relies on SQL to sift through mountains of data and pull out the gems. Whether you're running queries, shuffling databases around, or diving deep into analytics, SQL skills are a must-have.

For this reason, writing good SQL code is a go-to if you want to be able to use data properly. And since it’s not that simple, we'd like to share all the best practices that improve efficiency, readability, and performance of your SQL queries.

1. Understand the data structure

Before diving into query writing, it is essential you understand the data structure first. Familiarity with the database schema, which includes the tables, the columns within them, and the relationships between tables, is absolutely mandatory if you want to write good SQL queries.

Understanding how tables are linked - whether through one-to-one, one-to-many, or many-to-many relationships - can significantly influence the design of your query. Effective SQL queries are built on a foundation of clear knowledge about where relevant data is stored and how different pieces of data relate to each other. For instance, knowing whether to join tables or look for data in a single table can eliminate unnecessary complexity and enhance performance.

2. Use descriptive aliases

Aliases in SQL are shorthand for table or column names that can make queries easier to read and write. When using aliases, go for descriptive names that clearly communicate the content of the table or column they represent.

This practice becomes especially useful in complex queries involving multiple tables. For example, instead of using ab, or c, use aliases like employeedepartment, or sales.

Let's compare the readability of these two queries:

    • Less Descriptive: 
SELECT a.name, b.name FROM employees a 
JOIN departments b ON a.dept_id = b.dept_id;
    • More Descriptive:
SELECT emp.name, dept.name FROM employees emp 
JOIN departments dept ON emp.dept_id = dept.dept_id;

The second example makes it clear which name comes from which table, reducing confusion and making the query more maintainable.

3. Keep queries simple and maintainable

Complex SQL queries can be difficult to understand and maintain, especially as your database evolves or as new requirements emerge.

To enhance the clarity and maintainability of your SQL, break down complex queries into smaller, simpler parts. If a query uses multiple subqueries, consider whether some of the logic can be simplified or calculated in advance.

Avoid using too many nested queries and temporary tables as these can make the code harder to read and debug. Whenever possible, simplify conditions and computations, and aim for a series of smaller, well-defined queries that each solve a part of the problem, rather than one massive query trying to do everything at once.

4. Choose JOINs over subqueries

When you’re looking to boost your SQL query’s performance, choosing JOINs over subqueries can be a game changer. JOINs are generally faster and more efficient, especially in large databases, because they simplify the execution plan the database engine uses. For example, if you're looking to match customer information with their order details, using a JOIN can execute this more swiftly than a nested subquery.

Here are two examples:

    • Subquery: 
SELECT * FROM Orders WHERE customer_id 
IN(SELECT customer_id FROM Customers WHERE last_name = 'Smith');
    • JOIN: 
SELECT Orders.* FROM Orders JOIN Customers 
ON Orders.customer_id = Customers.customer_id
WHERE Customers.last_name = 'Smith';

The JOIN example is typically faster because it allows the database to optimize the query better and handle fewer rows overall.

5. Use WHERE clauses effectively

Filtering data with WHERE clauses right at the start of your queries can dramatically reduce the workload on your database. By doing this, you ensure that only the necessary data is processed in the subsequent steps of your query, which can lead to significant performance gains.

Let's compare these two examples:

    • Inefficient: 
SELECT first_name, last_name FROM Employees ORDER BY last_name DESC;
    • Efficient:
SELECT first_name, last_name FROM Employees WHERE department = 'Sales' 
ORDER BY last_name DESC;

In the efficient example, the database filters out employees outside the Sales department right away, meaning fewer records are sorted and processed in the ORDER BY step.

6. Leverage aggregate functions for data summarization

Aggregate functions like SUM, AVG, and COUNT are powerful tools for summarizing data. Used with GROUP BY, these functions can help you understand trends and patterns by grouping data into categories and calculating totals, averages, or counts for each group.

Here's an example:

SELECT department, COUNT(employee_id) FROM Employees GROUP BY department;

While useful, a common pitfall in using GROUP BY is not including all non-aggregated columns in the GROUP BY clause, which can lead to SQL errors or incorrect data grouping. Always ensure that any column in your SELECT that isn’t an aggregate function is also included in your GROUP BY clause.

7. Indexing for performance improvement

Indexes are like the table of contents in a book. They help the database quickly locate and retrieve data without scanning every row of a table, which dramatically improves query performance, particularly on large datasets. Creating effective indexes involves identifying the columns that are most frequently used in your WHERE clauses, JOIN conditions, or as part of an ORDER BY clause.

To improve your indexing follow these guidelines:

  • Prioritize indexing columns that are frequently used in query conditions.
  • Be smart with indexing; over-indexing can slow down write operations because each index needs to be updated.
  • Consider composite indexes if multiple columns are often queried together.

8. Avoid using SELECT *

Using SELECT * in queries can lead to several problems:

  • Performance impact: SELECT * pulls all columns from the table, including those not needed for the particular analysis, which can consume more I/O and slow down the query.

  • Maintenance issues: If the table structure changes (like adding or deleting columns), it can affect queries and their dependent applications unexpectedly.

Here's what we advise:

  • Always specify only the necessary columns in your SELECT statements. This not only speeds up queries but also makes your code clearer and less prone to errors from table modifications.

9. Write self-documenting SQL code

Clear, well-documented SQL code is crucial for maintainability, especially in collaborative environments. Comments and consistent formatting help others (and your future self) understand the logic behind complex queries and make updates easier.

Here's an example of well-documented SQL:

-- Calculate average sales by region for active stores
SELECT region, AVG(sales) AS average_sales
FROM stores
WHERE status = 'Active'
GROUP BY region
ORDER BY average_sales DESC;
A well-documented SQL should always:
  1. Use comments to explain "why" something is done, not just "what" is done.
  2. Follow a consistent style in capitalization, indentation, and aliasing for better readability.

10. Test and optimize queries

Testing and optimizing SQL queries are essential to ensure they not only run correctly but also perform well under various conditions.

Be sure to apply these two techniques:

  • Use EXPLAIN plans to understand how your query will be executed and identify potential bottlenecks.
  • Run queries during off-peak hours to test performance under less load.

Here's two tools for optimization:

  • SQL profilers and performance monitoring tools can help identify slow queries.
  • Index tuning wizards and query optimizers, available in most RDBMS, suggest performance improvements.


Now remember: correctness, readability and optimization (in that order) are the backbone of a good SQL query. If you follow these tips, you’ll soon become a SQL expert!


Ebook: build vs buy, how to choose

get the ebook
Ebook - Build vs buy - Openbook 2

Get the most out of your data with Toucan

Deploy anywhere with Toucan
Ebook - Build vs buy - cover
get the ebook

Table of Contents