SQL COUNT() for Beginners

In SQL, the COUNT() function is an aggregate function that returns the number of items found in a group.

You can use COUNT() in multiple parts of a query. For example, you can use it in the SELECT list, or the HAVING clause when filtering groups.

Sample Table

Suppose we have the following table:

SELECT * FROM Pets;

Result:

+---------+-------------+-----------+-----------+------------+
| PetId   | PetTypeId   | OwnerId   | PetName   | DOB        |
|---------+-------------+-----------+-----------+------------|
| 1       | 2           | 3         | Fluffy    | 2020-11-20 |
| 2       | 3           | 3         | Fetch     | 2019-08-16 |
| 3       | 2           | 2         | Scratch   | 2018-10-01 |
| 4       | 3           | 3         | Wag       | 2020-03-15 |
| 5       | 1           | 1         | Tweet     | 2020-11-28 |
| 6       | 3           | 4         | Fluffy    | 2020-09-17 |
| 7       | 3           | 2         | Bark      | NULL       |
| 8       | 2           | 4         | Meow      | NULL       |
+---------+-------------+-----------+-----------+------------+

The following examples will use the COUNT() function when querying this table.

Example

Here’s a simple example to get started.

SELECT COUNT(*) AS Count
FROM Pets;

Result:

+---------+
| Count   |
|---------|
| 8       |
+---------+

This tells us that there’s 8 rows in the table. We know that because we used the asterisk wildcard (*) to specify all rows and all columns.

Count a Specific Column

You can also specify a particular column to count. The COUNT() function only counts non-NULL results, so if you specify a column that contains NULL values, those values won’t be counted.

Here’s an example to demonstrate what I mean.

SELECT COUNT(DOB) AS Count
FROM Pets;

Result:

+---------+
| Count   |
|---------|
| 6       |
+---------+
Warning: Null value is eliminated by an aggregate or other SET operation.

In this case, the Pets table contains two NULL values in the DOB column (two pets haven’t supplied their date of birth), and so COUNT(DOB) returns 6, instead of 8 when we used COUNT(*).

The reason COUNT(*) in the previous example returned all rows, is because those two rows did have data in the other columns.

In my example, my DBMS also returned a warning about this. You may or may not get a warning, depending on your DBMS and your specific configuration.

Filtered Results

The COUNT() function counts the rows returned by the query. So if you filter the results, the result of COUNT() will reflect that.

SELECT COUNT(*) AS Count
FROM Pets
WHERE PetName = 'Fluffy';

Result:

+---------+
| Count   |
|---------|
| 2       |
+---------+

In this case, there are two pets with a name of Fluffy. Therefore, two rows would have been returned by the query, and the result of COUNT() is 2.

Count Distinct Columns

By default, the COUNT() function includes an implicit ALL keyword. This means that it includes duplicates in its results.

But you also have the option of adding the DISTINCT keyword to specify that just distinct values are returned. That is, you can specify that it excludes duplicates.

Let’s choose the PetName column. If you look at the original table above, you can see that the PetName column includes two rows with the same value (Fluffy).

First we’ll run a COUNT(ALL PetName) query to include all duplicate values in the count:

SELECT COUNT(ALL PetName) AS Count
FROM Pets;

Result:

+---------+
| Count   |
|---------|
| 8       |
+---------+

So, there are eight rows. Remember that this is the same result we would get if we hadn’t included the ALL keyword, because ALL is the default.

Now we’ll run a COUNT(DISTINCT PetName) to eliminate any duplicates from the count.

SELECT COUNT(DISTINCT PetName) AS Count
FROM Pets;

Result:

+---------+
| Count   |
|---------|
| 7       |
+---------+

This time the result is 7. This is because our duplicate value was eliminated. That is, the duplicate value was treated as if there was only one value.

Using COUNT() with the HAVING Clause

You can include the COUNT() function in multiple parts of a query. It’s not just limited to the SELECT list.

Here’s an example that uses COUNT() in both the HAVING clause and the SELECT list.

SELECT 
    PetTypeId, 
    COUNT(PetTypeId) AS Count
FROM Pets
GROUP BY PetTypeId
HAVING COUNT(PetTypeId) > 2
ORDER BY Count DESC;

Result:

+-------------+---------+
| PetTypeId   | Count   |
|-------------+---------|
| 3           | 4       |
| 2           | 3       |
+-------------+---------+

In this case, we used the HAVING clause in conjunction with the GROUP BY clause to return just those rows that have a COUNT(PetTypeId) of greater than 2.

You’re not limited to just the =, <, >=, IN, LIKE, etc).

See SQL Operators for a list of operators available in SQL.

Window Functions

Depending on your DBMS, you may be able to use an OVER clause with your COUNT() function to create a window function.

A window function performs an aggregate-like operation on a set of query rows. It produces a result for each query row. This is in contrast to an aggregate operation, which groups query rows into a single result row.

Here’s an example to demonstrate the concept.

We’ve already seen the Pets table. Our database also has an Owners table, and it contains the following data:

+-----------+-------------+------------+----------------+-------------------+
| OwnerId   | FirstName   | LastName   | Phone          | Email             |
|-----------+-------------+------------+----------------+-------------------|
| 1         | Homer       | Connery    | (308) 555-0100 | [email protected] |
| 2         | Bart        | Pitt       | (231) 465-3497 | [email protected]  |
| 3         | Nancy       | Simpson    | (489) 591-0408 | NULL              |
| 4         | Boris       | Trump      | (349) 611-8908 | NULL              |
| 5         | Woody       | Eastwood   | (308) 555-0112 | [email protected] |
| 6         | Burt        | Tyson      | (309) 565-0112 | [email protected]  |
+-----------+-------------+------------+----------------+-------------------+

We can retrieve data from these tables and present them as one result set by using a join.

We can also use the COUNT() function with the OVER clause to apply a window function to the data.

SELECT 
    CONCAT(o.FirstName, ' ', o.LastName) AS Owner,
    p.PetName,
    COUNT(PetId) OVER (PARTITION BY CONCAT(o.FirstName, ' ', o.LastName)) AS "Number of pets from this owner"
FROM Owners o 
INNER JOIN Pets p 
ON p.OwnerId = o.OwnerId
ORDER BY "Number of pets from this owner" DESC;

Result:

+---------------+-----------+----------------------------------+
| Owner         | PetName   | Number of pets from this owner   |
|---------------+-----------+----------------------------------|
| Nancy Simpson | Wag       | 3                                |
| Nancy Simpson | Fluffy    | 3                                |
| Nancy Simpson | Fetch     | 3                                |
| Bart Pitt     | Scratch   | 2                                |
| Bart Pitt     | Bark      | 2                                |
| Boris Trump   | Meow      | 2                                |
| Boris Trump   | Fluffy    | 2                                |
| Homer Connery | Tweet     | 1                                |
+---------------+-----------+----------------------------------+

In this case we used the OVER clause with our COUNT() clause to partition the count to just the owner’s name.

The result is that owners with multiple pets are displayed on multiple rows (because each pet also has to be displayed), and each row contains the aggregate count of that owner’s pets.

This concept can also be applied to other aggregate functions in SQL, such as SUM(), MIN(), MAX(), and AVG().

COUNT_BIG()

If you’re counting seriously large data sets in SQL Server, you might find that the COUNT() function produces an error, due to the number being too high. This will only happen your count is greater than 2,147,483,647.

In such cases, you can use COUNT_BIG(), which can cater for much larger numbers.

See How COUNT_BIG() Works in SQL Server and COUNT() vs COUNT_BIG() for a more detailed explanation.

ANSI SQL Standard

The COUNT() function is listed in the SQL standard, and it is available in most (if not all) of the major DBMSs, and works pretty much the same across them.

For code examples done in various DBMSs, see SQLite COUNT(), SQL Server COUNT(), and MySQL COUNT().