Функция COUNT (Transact-SQL)
Эта функция возвращает количество элементов, найденных в группе. Функция COUNT работает подобно функции COUNT_BIG. Эти функции различаются только типами данных в возвращаемых значениях. Функция COUNT всегда возвращает значение типа данных int. Функция COUNT_BIG всегда возвращает значение типа данных bigint.
Синтаксис
Синтаксис функции агрегирования
COUNT ( < [ [ ALL | DISTINCT ] expression ] | * >)
Синтаксис функции аналитики
COUNT ( [ ALL ] < expression | * >) OVER ( [ ] )
Сведения о синтаксисе Transact-SQL для SQL Server 2014 (12.x) и более ранних версиях см . в документации по предыдущим версиям.
Аргументы
ВСЕ
Применяет агрегатную функцию ко всем значениям. Аргумент ALL используется по умолчанию.
DISTINCT
Указывает, что функция COUNT возвращает количество уникальных значений, не равных NULL.
выражение
Выражение любого типа, кромеimage, ntext и text. COUNT не поддерживает агрегатные функции или вложенные запросы в выражении.
Указывает, что функция COUNT должна учитывать все строки, чтобы определить общее количество строк таблицы для возврата. COUNT(*) не принимает параметров и не поддерживает использование DISTINCT. COUNT(*) не требует параметра выражения, так как по определению он не использует сведения о определенном столбце. Функция COUNT(*) возвращает количество строк в указанной таблице с учетом повторяющихся строк. Она подсчитывает каждую строку отдельно. При этом учитываются и строки, содержащие значения NULL.
OVER ( [ partition_by_clause ] [ order_by_clause ] [ ROW_or_RANGE_clause ] )
partition_by_clause делит результирующий набор, полученный с помощью предложения FROM , на секции, к которым применяется функция COUNT . Если этот параметр не указан, функция обрабатывает все строки результирующего набора запроса как отдельные группы. order_by_clause определяет логический порядок выполнения операции. Дополнительные сведения см . в предложении OVER (Transact-SQL ).
Типы возвращаемых данных
- int NOT NULL , ANSI_WARNINGS если имеет значение ON , однако SQL Server всегда будет обрабатывать COUNT выражения как int NULL в метаданных, если только не упакованы в ISNULL .
- int NULL , если ANSI_WARNINGS имеет значение OFF .
Замечания
- COUNT(*) без GROUP BY возврата карта inality (количество строк) в наборе результатов. К ним относятся строки, состоящие из всех NULL значений и дубликатов.
- COUNT(*) при GROUP BY возврате числа строк в каждой группе. Сюда входят NULL значения и дубликаты.
- COUNT(ALL ) вычисляет выражение для каждой строки в группе и возвращает количество ненулевого значения.
- COUNT(DISTINCT *expression*) вычисляет выражение для каждой строки в группе и возвращает количество уникальных, ненулевого значения.
COUNT — это детерминированная функция, если она используется без предложений OVER и ORDER BY. Она не детерминирована при использовании с предложениями OVER и ORDER BY. Дополнительные сведения см. в разделе детерминированные и недетерминированные функции.
ARITHABORT и ANSI_WARNINGS .
Если COUNT имеет возвращаемое значение, превышающее максимальное значение int (то есть 2 31-1 или 2 147 483 647), COUNT функция завершится ошибкой из-за целочисленного переполнения. При COUNT переполнении и параметрах ARITHABORT OFF COUNT ANSI_WARNINGS возвращается. NULL В противном случае, если или есть, ANSI_WARNINGS ARITHABORT ON запрос будет прерваться, и будет вызвана ошибка арифметического переполнения. Msg 8115, Level 16, State 2; Arithmetic overflow error converting expression to data type int. Чтобы правильно обрабатывать эти большие результаты, используйте COUNT_BIG вместо этого, что возвращает bigint.
Если оба ARITHABORT и ANSI_WARNINGS есть ON , вы можете безопасно упаковать COUNT сайты вызовов, ISNULL( , 0 ) чтобы принудить тип выражения вместо int NOT NULL int NULL . Упаковка COUNT в ISNULL означает, что любая ошибка переполнения будет автоматически подавляться, что должно быть рассмотрено для правильности.
Примеры
А. Использование COUNT и DISTINCT
В этом примере возвращается количество различных названий, которые может хранить сотрудник Adventure Works Cycles.
SELECT COUNT(DISTINCT Title) FROM HumanResources.Employee; GO
----------- 67 (1 row(s) affected)
B. Использование COUNT(*)
В этом примере возвращается общее количество сотрудников Adventure Works Cycles.
SELECT COUNT(*) FROM HumanResources.Employee; GO
----------- 290 (1 row(s) affected)
C. Использование COUNT(*) с другими агрегатами
В этом примере показано, что функция COUNT(*) работает с другими статистическими функциями в списке SELECT . В примере используется база данных AdventureWorks2022.
SELECT COUNT(*), AVG(Bonus) FROM Sales.SalesPerson WHERE SalesQuota > 25000; GO
----------- --------------------- 14 3472.1428 (1 row(s) affected)
D. Использование предложения OVER
В этом примере используются MAX AVG MIN функции и COUNT функции с OVER предложением для возврата агрегированных значений для каждого отдела в таблице базы данных HumanResources.Department AdventureWorks2022.
SELECT DISTINCT Name , MIN(Rate) OVER (PARTITION BY edh.DepartmentID) AS MinSalary , MAX(Rate) OVER (PARTITION BY edh.DepartmentID) AS MaxSalary , AVG(Rate) OVER (PARTITION BY edh.DepartmentID) AS AvgSalary , COUNT(edh.BusinessEntityID) OVER (PARTITION BY edh.DepartmentID) AS EmployeesPerDept FROM HumanResources.EmployeePayHistory AS eph JOIN HumanResources.EmployeeDepartmentHistory AS edh ON eph.BusinessEntityID = edh.BusinessEntityID JOIN HumanResources.Department AS d ON d.DepartmentID = edh.DepartmentID WHERE edh.EndDate IS NULL ORDER BY Name;
Name MinSalary MaxSalary AvgSalary EmployeesPerDept ----------------------------- --------------------- --------------------- --------------------- ---------------- Document Control 10.25 17.7885 14.3884 5 Engineering 32.6923 63.4615 40.1442 6 Executive 39.06 125.50 68.3034 4 Facilities and Maintenance 9.25 24.0385 13.0316 7 Finance 13.4615 43.2692 23.935 10 Human Resources 13.9423 27.1394 18.0248 6 Information Services 27.4038 50.4808 34.1586 10 Marketing 13.4615 37.50 18.4318 11 Production 6.50 84.1346 13.5537 195 Production Control 8.62 24.5192 16.7746 8 Purchasing 9.86 30.00 18.0202 14 Quality Assurance 10.5769 28.8462 15.4647 6 Research and Development 40.8654 50.4808 43.6731 4 Sales 23.0769 72.1154 29.9719 18 Shipping and Receiving 9.00 19.2308 10.8718 6 Tool Design 8.62 29.8462 23.5054 6 (16 row(s) affected)
Примеры: Azure Synapse Analytics и система платформы аналитики (PDW)
Д. Использование COUNT и DISTINCT
В этом примере функция возвращает количество различных должностей, которые может иметь конкретный сотрудник компании.
USE ssawPDW; SELECT COUNT(DISTINCT Title) FROM dbo.DimEmployee;
F. Использование COUNT(*)
В этом примере функция возвращает общее количество строк в таблице dbo.DimEmployee .
USE ssawPDW; SELECT COUNT(*) FROM dbo.DimEmployee;
G. Использование COUNT(*) с другими агрегатами
В этом примере функция COUNT(*) работает с другими статистическими функциями в списке SELECT . Запрос возвращает количество торговых представителей с годовой квотой продаж более 500 000 долл. США и их среднюю квоту продаж.
USE ssawPDW; SELECT COUNT(EmployeeKey) AS TotalCount, AVG(SalesAmountQuota) AS [Average Sales Quota] FROM dbo.FactSalesQuota WHERE SalesAmountQuota > 500000 AND CalendarYear = 2001;
TotalCount Average Sales Quota ---------- ------------------- 10 683800.0000
H. Использование COUNT с ПОМОЩЬЮ HAVING
В этом примере функция COUNT используется с предложением HAVING , чтобы получить список подразделений компании, в каждом из которых работает более 15 сотрудников.
USE ssawPDW; SELECT DepartmentName, COUNT(EmployeeKey)AS EmployeesInDept FROM dbo.DimEmployee GROUP BY DepartmentName HAVING COUNT(EmployeeKey) > 15;
DepartmentName EmployeesInDept -------------- --------------- Sales 18 Production 179
I. Использование COUNT с OVER
В этом примере функция COUNT используется с предложением OVER , чтобы получить количество продуктов, содержащихся в каждом из указанных заказов на продажу.
USE ssawPDW; SELECT DISTINCT COUNT(ProductKey) OVER(PARTITION BY SalesOrderNumber) AS ProductCount , SalesOrderNumber FROM dbo.FactInternetSales WHERE SalesOrderNumber IN (N'SO53115',N'SO55981');
ProductCount SalesOrderID ------------ ----------------- 3 SO53115 1 SO55981
См. также
- Агрегатные функции (Transact-SQL)
- COUNT_BIG (Transact-SQL)
- Предложение OVER (Transact-SQL)
Как посчитать null в sql
Есть таблица [user] с пользователями. В этой таблице есть колонка [status] , которая хранит текстовый статус пользователя (может равняться NULL). Требуется подсчитать количество пользователей для каждого статуса. Делаю это так:
SELECT [status], COUNT([status]) as users_count FROM [users] GROUP BY [status]
Проблема в том, что нужно также узнать количетсво пользователей, у которых [status] IS NULL . А приведенный запрос всегда возвращает 0, хотя в таблице есть строки с незаполненным статусом:
status | users_count ---------------------- NULL | 0 ← тут всегда 0 status1 | 13 status2 | 21
Такое ощущение, что строки со значением NULL игнорируются при подсчете count.
Значение NULL в SQL – неизвестное значение
Примечание:
Во всех статьях текущей категории уроков по SQL используются примеры и задачи, основанные на учебной базе данных.
Приступая к изучению данного материала, рекомендуется ознакомиться с описанием учебной БД.
Даже для небольших баз данных часто встречаются ситуации, когда значение какого-либо поля таблицы может быть неизвестно. Причины возникновения подобных ситуаций могут быть разными, начиная ошибками ПО и проектирования БД, заканчивая особенностями бизнес-процессов организации.
Если рассмотреть диаграмму таблицы сотрудников учебной БД, то можно заметить, что последний столбец диаграммы указывает возможность наличия неизвестных значение в конкретном поле, а именно:
- Отчество. Вполне возможно, что сотрудником является гражданин страны, где не используется отчество.
- Дата увольнения может отсутствовать, так как увольнения еще не было.
- Группа может быть неизвестна, потому что сотрудник может быть не распределен в группу на каком-то из этапов приема на работу.
Важно понять, что неизвестные (отсутствующие) значения – это не ноль (для числовых полей) и не пустая строка (для текстовых полей). Так как ноль является вполне конкретным значением, например, 0 рублей задолженности, а пустая строка сообщает о том, что на данный момент ничего кроме строки нулевой длины в поле строки быть не должно. В примере с отчеством, приведенном выше, вместо значения NULL можно задать пустую строку и это внесло бы дополнительную ясность, что отчество сотрудника нет в принципе, а не то, что его забыли внести.
Поиск отсутствующих значений
Выше было определено, что NULL не является конкретным значением, поэтому нужно понять, как операторы сравнения с ним будут работать. Никакое значение не может быть равно (также быть больше или меньше) неизвестному значению, даже условие NULL = NULL является ложным. Чтобы определить отсутствующее значения используется специальное условие IS NULL (является неизвестным). И наоборот, если требуется найти известные значения, то задается условие IS NOT NULL.
Рассмотрим задачу.
Найти всех сотрудников, которые были когда-либо уволены.
Решение.
Если в поле «Дата_увольнения» таблицы сотрудников отсутствует значение, то сотрудники работают на данный момент. Следовательно, нужно найти строки, где значение известно. Следующий sql-запрос выведет 7 строк, удовлетворяющих решению:
USE CallCenter SELECT * FROM Сотрудники WHERE Дата_увольнения IS NOT NULL
Решим еще одну задачу.
Вывести непринятые звонки за 1 декабря 2014 года.
Решение.
Звонок считается непринятым, если в таблице «Звонки» в поле «Сотрудник» отсутствует id принявшего звонок оператора. Отфильтровав таблицу по полям «Сотрудник» и «Дата_Время», получим 184 строки, удовлетворяющих запросу:
USE CallCenter SELECT * FROM Звонки WHERE Сотрудник IS NULL AND Дата_Время >= '01/12/2014 00:00:00' AND Дата_Время < '02/12/2014 00:00:00'
Обработка неизвестных значений
Если в своих запросах, Вы будете использовать поля, которые допускают значения NULL, то обязательно обрабатывайте такие поля, чтобы избежать ошибок. Например, любые арифметические операции или объединения строк, где в качестве аргумента будет хотя бы одно значение NULL, вернут неизвестное значение.
Рассмотрим пример.
Необходимо определить стаж работы каждого сотрудника, включая уволенных, на текущий момент. Стаж вывести в днях.
Для определения стажа необходимо найти интервал (разницу) между датой найма сотрудника и датой увольнения. Для этого можно использовать функцию DATEDIFF (ее описание можно найти в документации Microsoft). Но как быть с не уволенными сотрудниками, у которых отсутствует значение даты увольнения? Если выполнить ниже приведенный запрос, то можно убедиться, что большинство строк не покажут стаж:
USE CallCenter SELECT id, DATEDIFF(DAY, Дата_найма, Дата_увольнения) AS Стаж FROM Сотрудники
Поэтому обработаем поле «Дата_увольнения», применив функции ISNULL (если первый аргумент является NULL, то функция возвращает второй аргумент) и GETDATE (возвращает текущую системную дату и время). Следующий запрос выведет стаж в каждой строке:
USE CallCenter SELECT id, DATEDIFF(DAY, Дата_найма, ISNULL(Дата_увольнения, GETDATE())) AS Стаж FROM Сотрудники
- Объединение таблиц – UNION
- Соединение таблиц – операция JOIN и ее виды
- Тест на знание основ SQL
Если материалы office-menu.ru Вам помогли, то поддержите, пожалуйста, проект, чтобы я мог развивать его дальше.
NULL значения в агрегатных функциях
NULL значения в агрегатных функциях обрабатываются по особому - они игнорируются. Поэкспериментируем на таблице:
SELECT * FROM table1
| value |
|---|
| 1 |
| 2 |
| 3 |
| NULL |
Получим минимальное и максимальное значение:
SELECT min(value) as min_value, max(value) as max_value FROM table1
| min_value | max_value |
|---|---|
| 1 | 3 |
Исключением является функция count(*) , возвращающая общее количество строк в выборке. count(*) не принимает на вход никакого выражения, а просто возвращает количество строк в выборке, независимо от наличия NULL значений. Чтобы посчитать количество не NULL значений в столбце, необходимо воспользоваться функцией count(выражение) . Например:
SELECT count(value) as count_value, count(*) as count_rows FROM table1
| count_value | count_rows |
|---|---|
| 3 | 4 |
