SUM: примеры (SQL)
SUM(expression numeric): Depends on expression (numeric)Описание функции SUM в MS SQL
Функция SUM является агрегатной функцией в Transact-SQL, предназначенной для вычисления суммы значений в наборе данных. Она используется в операторах SELECT, HAVING и ORDER BY, преимущественно с числовыми типами данных.
Функция применяется, когда требуется получить итоговое значение по группе строк, например общую сумму продаж, сумму затрат или количество баллов.
Синтаксис функции: SUM ( [ ALL | DISTINCT ] выражение )
Аргументы:
- ALL: применяет функцию ко всем значениям в группе. Этот параметр используется по умолчанию, если не указан иной.
- DISTINCT: указывает, что функция должна учитывать только уникальные значения выражения перед выполнением суммирования.
- выражение: константа, имя столбца, функция или комбинация операторов и функций, результатом которой является числовое значение. Типы данных
bit,tinyint,smallint,int,bigint,decimal,numeric,money,smallmoney,float,realдопускаются, за исключением типаbit.
Возвращаемое значение:
- Тип возвращаемого значения определяется типом аргумента
выражение. - Для типа выражения
tinyint,smallint,intфункция возвращаетint. - Для типа выражения
bigintвозвращаетсяbigint. - Для типов
decimalиnumericвозвращаетсяdecimal, с точностью и масштабом, определяемыми правилами SQL Server. - Для типов
moneyиsmallmoneyвозвращаетсяmoney. - Для типов
floatиrealвозвращаетсяfloat. - Если набор строк пуст или все значения NULL, функция возвращает
NULL.
Простые примеры использования
Пример 1: Сумма всех значений в столбце.
SELECT SUM(Quantity) AS TotalQuantity FROM Sales.OrderLines;TotalQuantity
-------------
1234567Пример 2: Использование с параметром DISTINCT.
SELECT SUM(DISTINCT UnitPrice) AS SumDistinctPrices FROM Sales.OrderLines WHERE StockItemID = 10;SumDistinctPrices
-----------------
456.23Пример 3: SUM в комбинации с GROUP BY.
SELECT CustomerID, SUM(TransactionAmount) AS TotalSpent FROM Sales.CustomerTransactions GROUP BY CustomerID;CustomerID TotalSpent
---------- -----------
123 5678.90
124 1234.50Пример 4: Использование с HAVING.
SELECT SupplierID, SUM(SupplyQuantity) AS TotalSupplied FROM Purchasing.PurchaseOrders GROUP BY SupplierID HAVING SUM(SupplyQuantity) > 1000;Похожие агрегатные функции в MS SQL
- AVG: вычисляет среднее арифметическое набора значений. Предпочтительна для анализа средних показателей, например средней цены товара.
- COUNT: подсчитывает количество элементов в группе. Используется, когда нужен подсчет строк или не-NULL значений.
- MIN/MAX: находят минимальное и максимальное значение в наборе. Применяются для поиска граничных значений.
- STDEV/VAR: статистические функции для вычисления стандартного отклонения и дисперсии. Используются в аналитических задачах.
Функцию SUM выбирают, когда необходима именно аддитивная операция сложения числовых величин, например для подведения итогов.
Типичные ошибки при работе с SUM
Ошибка 1: Суммирование нечисловых данных приводит к ошибке преобразования типов.
-- Столбец Name имеет тип varchar
SELECT SUM(Name) FROM Products;Сообщение 8117, уровень 16, состояние 1. Ошибка преобразования типа данных varchar к numeric.
Ошибка 2: Игнорирование NULL значений. NULL не участвует в операции сложения, что иногда приводит к непониманию логики расчета.
SELECT SUM(col) FROM (VALUES (5), (NULL), (10)) AS t(col);15
Ошибка 3: Переполнение при суммировании больших значений, особенно для целочисленных типов.
SELECT SUM(CAST(2147483647 AS int) + 1); -- Выход за пределы intСообщение 8115, уровень 16, состояние 2. Арифметическое переполнение.
Ошибка 4: Использование в неправильном контексте, например, без GROUP BY в запросе с другими неагрегированными столбцами.
SELECT CustomerID, OrderID, SUM(Amount) FROM Sales.Orders;Сообщение 8120, уровень 16, состояние 1. Столбец "Sales.Orders.OrderID" недопустим в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY.
Изменения в последних версиях SQL Server
Семантика и синтаксис функции SUM остаются стабильными на протяжении многих версий SQL Server. Существенных изменений в поведении или аргументах функции в версиях 2016, 2017, 2019 и 2022 не зафиксировано. Основные улучшения связаны с оптимизацией выполнения запросов и работой с новыми типами индексов (например, columnstore), что может влиять на производительность агрегатных операций, включая SUM.
Расширенные примеры применения
Пример 1: Сумма с условием внутри выражения.
SELECT SUM(CASE WHEN Quantity > 10 THEN Quantity * 0.9 ELSE Quantity END) AS AdjustedSum FROM Sales.OrderLines;AdjustedSum ----------- 987654.32
Пример 2: Использование оконной функции SUM для нарастающего итога.
SELECT OrderDate, TransactionAmount,
SUM(TransactionAmount) OVER (ORDER BY OrderDate) AS RunningTotal
FROM Sales.CustomerTransactions
ORDER BY OrderDate;OrderDate TransactionAmount RunningTotal ---------- ----------------- ------------ 2023-01-01 100.00 100.00 2023-01-02 50.00 150.00 2023-01-03 75.00 225.00
Пример 3: Вложенный запрос с агрегацией.
SELECT CustomerCategoryName,
(SELECT SUM(TransactionAmount)
FROM Sales.CustomerTransactions ct
JOIN Sales.Customers c ON ct.CustomerID = c.CustomerID
WHERE c.CustomerCategoryID = cc.CustomerCategoryID) AS CategoryTotal
FROM Sales.CustomerCategories cc;Пример 4: SUM с фильтром NULLIF для исключения специфических значений из расчета.
SELECT SUM(NULLIF(Quantity, 0)) AS SumWithoutZeros FROM Sales.OrderLines;Пример 5: Суммирование выражений с разными типами данных (деньги и decimal).
SELECT SUM(CAST(TransactionAmount AS decimal(19,4)) + TaxAmount) AS TotalWithTax FROM Sales.CustomerTransactions;Пример 6: Использование в выражении для вычисления доли.
SELECT StockGroupID,
SUM(Quantity) AS GroupQuantity,
SUM(Quantity) * 100.0 / (SELECT SUM(Quantity) FROM Sales.OrderLines) AS Percentage
FROM Sales.OrderLines
GROUP BY StockGroupID;Аналоги функции в других СУБД
MySQL: Синтаксис аналогичен. Отличие в неявном приведении типов и поведении с NULL.
SELECT SUM(amount) FROM payments;Oracle: Функция SUM также работает в контексте аналитических функций (OVER).
SELECT department_id, SUM(salary) OVER (PARTITION BY department_id) FROM employees;PostgreSQL: Поведение схоже с SQL Server. Поддерживает фильтрацию внутри агрегатной функции.
SELECT SUM(quantity) FILTER (WHERE product_id = 1) FROM order_items;SQLite: Функция SUM существует, но типизация динамическая, что может приводить к неявным преобразованиям.
SELECT SUM(column) FROM table;Sybase ASE: Синтаксис и поведение практически идентичны MS SQL, учитывая общие корни.