SUM: примеры (SQL)

Использование SUM для подсчета суммы в SQL Server
Раздел: Агрегатные функции, Агрегатные
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: Сумма с условием внутри выражения.

Пример sql
SELECT SUM(CASE WHEN Quantity > 10 THEN Quantity * 0.9 ELSE Quantity END) AS AdjustedSum FROM Sales.OrderLines;
AdjustedSum
-----------
   987654.32

Пример 2: Использование оконной функции SUM для нарастающего итога.

Пример sql
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: Вложенный запрос с агрегацией.

Пример sql
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 для исключения специфических значений из расчета.

Пример sql
SELECT SUM(NULLIF(Quantity, 0)) AS SumWithoutZeros FROM Sales.OrderLines;

Пример 5: Суммирование выражений с разными типами данных (деньги и decimal).

Пример sql
SELECT SUM(CAST(TransactionAmount AS decimal(19,4)) + TaxAmount) AS TotalWithTax FROM Sales.CustomerTransactions;

Пример 6: Использование в выражении для вычисления доли.

Пример sql
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, учитывая общие корни.

MS SQL SUM function comments

En
SUM Returns the sum of all values in the expression