Skip to main content
Data Query Language (DQL) is the heart of SQL. Almost every interaction you have with a database involves a SELECT statement, and learning to write precise, efficient queries is one of the most valuable skills you can build. This chapter covers the full SELECT toolkit: choosing columns, filtering rows with WHERE, eliminating duplicates with DISTINCT, sorting with ORDER BY, paginating with LIMIT and OFFSET, performing calculations with aggregate functions, grouping data with GROUP BY, and filtering groups with HAVING. Throughout, you’ll use the sample Employee and Department tables you set up in the previous chapter.

Reference Tables

All examples in this chapter use these tables: Department: Employee:

SELECT Statement

The SELECT statement retrieves data from one or more tables. Retrieve all columns:
Retrieve specific columns:
Write a query to display only employee names and cities.

Column Aliases

Use AS to give a column a temporary display name. Aliases make output easier to read and are especially useful when performing calculations.
Display employee names as Employee and salaries as Salary.

DISTINCT

DISTINCT removes duplicate values from a result set, returning only unique values.

WHERE Clause

The WHERE clause filters rows based on a condition. Only rows that satisfy the condition appear in the result.

Comparison Operators

Logical Operators

Combine multiple conditions with AND, OR, and NOT. AND — both conditions must be true:
OR — at least one condition must be true:
NOT — negates a condition:

BETWEEN

BETWEEN tests whether a value falls within an inclusive range.

IN

IN checks whether a value matches any item in a list, replacing multiple OR conditions.

LIKE

LIKE matches text patterns using wildcard characters.

NULL Values

Use IS NULL or IS NOT NULL to find rows where a value is missing or present.
You cannot use = NULL to test for missing values in SQL. You must always use IS NULL or IS NOT NULL.

ORDER BY

ORDER BY sorts the result set by one or more columns.

LIMIT and OFFSET

LIMIT restricts how many rows are returned. OFFSET skips a number of rows before starting to return results — useful for pagination.

Aggregate Functions

Aggregate functions perform calculations across multiple rows and return a single value.

GROUP BY

GROUP BY groups rows that share the same value in one or more columns, then applies an aggregate function to each group.

HAVING

HAVING filters groups after aggregation, whereas WHERE filters individual rows before grouping. Use HAVING whenever your filter condition involves an aggregate function.
A quick way to remember the difference: WHERE filters rows, HAVING filters groups. You write WHERE before GROUP BY and HAVING after it.

SQL Execution Order

You write SQL clauses in this order:
But SQL executes them in a different order:
This explains why column aliases created in SELECT cannot be used in WHEREWHERE runs before SELECT, so the alias doesn’t exist yet at that point.

Summary

In this chapter you learned how to:
  • Retrieve data using SELECT with specific columns or *
  • Rename output columns with AS aliases
  • Remove duplicates using DISTINCT
  • Filter rows with WHERE, comparison operators, AND/OR/NOT, BETWEEN, IN, LIKE, and IS NULL
  • Sort results with ORDER BY (ascending and descending)
  • Limit rows with LIMIT and OFFSET
  • Calculate totals, averages, counts, and extremes with aggregate functions
  • Group rows with GROUP BY
  • Filter groups with HAVING
  • Understand SQL’s execution order
The next chapter introduces SQL JOINs, which let you combine data from multiple tables in a single query.