В SQL, SUM()
функцията е агрегатна функция, която връща сумата от всички стойности в даден израз.
Може също да се използва за връщане на сумата от всички различни (уникални) стойности в израз.
Изразът трябва да е числов (не може да бъде низ от знаци, битов низ или дата и час).
По-долу са дадени няколко основни примера, за да демонстрирате как работи.
Примерна таблица
Да предположим, че имаме следната таблица:
SELECT * FROM Products;
Резултат:
+-------------+------------+---------------------------------+----------------+-----------------------------------------+ | ProductId | VendorId | ProductName | ProductPrice | ProductDescription | |-------------+------------+---------------------------------+----------------+-----------------------------------------| | 1 | 1001 | Left handed screwdriver | 25.99 | Purple. Includes left handed carry box. | | 2 | 1001 | Long Weight (blue) | 14.75 | Includes a long wait. | | 3 | 1001 | Long Weight (green) | 11.99 | Approximate 30 minute waiting period. | | 4 | 1002 | Sledge Hammer | 33.49 | Wooden handle. Free wine glasses. | | 5 | 1003 | Chainsaw | 245.00 | Orange. Includes spare fingers. | | 6 | 1003 | Straw Dog Box | NULL | Tied with vines. Very chewable. | | 7 | 1004 | Bottomless Coffee Mugs (4 Pack) | 9.99 | Brown ceramic with solid handle. | | 8 | 1001 | Right handed screwdriver | 25.99 | Blue. Includes right handed carry box. | +-------------+------------+---------------------------------+----------------+-----------------------------------------+
Пример
Можем да използваме следната заявка, за да получим сумата от всички цени.
SELECT SUM(ProductPrice)
FROM Products;
Резултат:
+--------------------+ | (No column name) | |--------------------| | 367.20 | +--------------------+
В този случай информацията за цената се съхранява в ProductPrice
колона и затова предаваме това като аргумент на SUM()
функция, която след това изчислява сумата и връща резултата.
Използване на псевдоними на колони
Ще забележите, че предишните резултати не включват име на колона. Това може да се очаква, тъй като SUM()
функцията не връща никакви колони. Можете лесно да предоставите име на колона, като зададете псевдоним.
SELECT SUM(ProductPrice) AS Sum
FROM Products;
Резултат:
+--------+ | Sum | |--------| | 367.20 | +--------+
Филтрирани резултати
SUM()
функцията работи с редовете, върнати от заявката. Така че, ако филтрирате резултатите, резултатът от SUM()
ще отрази това.
SELECT SUM(ProductPrice) AS Sum
FROM Products
WHERE VendorId = 1001;
Резултат:
+-------+ | Sum | |-------| | 78.72 | +-------+
В този случай 78,72 е сумата от всички продукти, предлагани от посочения доставчик.
NULL
Стойности
SUM()
функцията игнорира всеки NULL
стойности. В нашата примерна таблица по-горе продуктов номер 6
има NULL
в неговия ProductPrice
колона, но това беше игнорирано в нашия SUM()
пример.
В зависимост от вашата СУБД и настройките ви може или не може да видите предупреждение, че NULL
стойностите бяха елиминирани в набора от резултати.
Ето пример за това, което може да видите:
SELECT SUM(ProductPrice) AS Sum
FROM Products;
Резултат:
+--------+ | Sum | |--------| | 367.20 | +--------+ Warning: Null value is eliminated by an aggregate or other SET operation.
Всичко това ни казва, че колоната съдържа поне един NULL
стойност и че е била игнорирана при изчисляване на резултатите.
Данни за дата/час
SUM()
функцията не приема изрази за дата/час.
Да предположим, че имаме следната таблица:
SELECT PetName, DOB
FROM Pets;
Резултат:
+-----------+------------+ | PetName | DOB | |-----------+------------| | Fluffy | 2020-11-20 | | Fetch | 2019-08-16 | | Scratch | 2018-10-01 | | Wag | 2020-03-15 | | Tweet | 2020-11-28 | | Fluffy | 2020-09-17 | | Bark | NULL | | Meow | NULL | +-----------+------------+
Ако се опитаме да използваме SUM()
на DOB
колона, ще получим грешка.
SELECT SUM(DOB) AS Sum
FROM Pets;
Резултат:
Msg 8117, Level 16, State 1, Line 1 Operand data type date is invalid for sum operator.
Данни за знаци
SUM()
функцията също не приема изрази за низ от символи.
Ето какво се случва, ако се опитаме да използваме SUM()
на ProductName
колона на нашите Products
таблица (която използва тип данни varchar):
SELECT SUM(ProductName) AS Sum
FROM Products;
Резултат:
Msg 8117, Level 16, State 1, Line 1 Operand data type varchar is invalid for sum operator.
DISTINCT
Ключова дума
Можете да използвате DISTINCT
ключова дума с SUM()
за изчисляване само на различни стойности. Тоест, ако има дублиращи се стойности, те се третират като една стойност.
Пример:
SELECT SUM(DISTINCT ProductPrice) AS DistinctSum
FROM Products;
Резултат:
+---------------+ | DistinctSum | |---------------| | 341.21 | +---------------+
Можем да видим, че този резултат е по-нисък от резултата, който получихме без DISTINCT
ключова дума.
За да обобщим, получихме 367,20 без DISTINCT
ключова дума и 341.21 с DISTINCT
ключова дума.
Това е така, защото има два артикула, които споделят една и съща цена (отвертката с лява ръка и отвертката с дясна ръка са на цена 25,99). Следователно, SUM()
функция, когато се използва с DISTINCT
ключова дума, третира и двете стойности като една и съответно изчислява резултата си.
Функции на прозореца
В зависимост от вашата СУБД, може да сте в състояние да използвате OVER
клауза с вашия SUM()
функция за създаване на прозоречна функция.
Прозоречната функция изпълнява агрегатно-подобна операция върху набор от редове на заявка. Той произвежда резултат за всеки ред на заявката. Това е в контраст с агрегирана операция, която групира редовете на заявката в един ред с резултати.
Ето пример за демонстриране на концепцията.
Вече видяхме Products
маса. Нашата база данни също има Customers
таблица и съдържа следните данни:
+--------------+----------------------+-------------------+------------+-----------------+------------+-----------+----------------+ | CustomerId | CustomerName | PostalAddress | City | StateProvince | ZipCode | Country | Phone | |--------------+----------------------+-------------------+------------+-----------------+------------+-----------+----------------+ | 1001 | Palm Pantry | 20 Esplanade | Townsville | QLD | 2040 | AUS | (308) 555-0100 | | 1002 | Tall Poppy | 12 Main Road | Columbus | OH | 43333 | USA | (310) 657-0134 | | 1003 | Crazy Critters | 10 Infinite Loops | Cairns | QLD | 4870 | AUS | (418) 555-0143 | | 1004 | Oops Media | 4 Beachside Drive | Perth | WA | 1234 | AUS | (405) 443-5987 | | 1005 | Strange Names Inc. | 789 George Street | Sydney | NSW | 2000 | AUD | (318) 777-0177 | | 1006 | Hi-Five Solutionists | 5 High Street | Highlands | HI | 1254 | AUS | (415) 413-5182 | +--------------+----------------------+-------------------+------------+-----------------+------------+-----------+----------------+
Можем да извлечем данни от тези таблици и да ги представим като един набор от резултати, като използваме присъединяване.
Можем също да използваме SUM()
функция с OVER
клауза за прилагане на прозоречна функция към данните.
SELECT
v.VendorName,
p.ProductName,
p.ProductPrice,
SUM(ProductPrice) OVER (PARTITION BY v.VendorName) AS "Sum For This Vendor"
FROM Products p
INNER JOIN Vendors v
ON v.VendorId = p.VendorId
ORDER BY VendorName, ProductPrice, "Sum For This Vendor";
Резултат:
+---------------+---------------------------------+----------------+-----------------------+ | VendorName | ProductName | ProductPrice | Sum For This Vendor | |---------------+---------------------------------+----------------+-----------------------| | Katty Kittens | Bottomless Coffee Mugs (4 Pack) | 9.99 | 9.99 | | Mars Supplies | Long Weight (green) | 11.99 | 78.72 | | Mars Supplies | Long Weight (blue) | 14.75 | 78.72 | | Mars Supplies | Right handed screwdriver | 25.99 | 78.72 | | Mars Supplies | Left handed screwdriver | 25.99 | 78.72 | | Pedal Medals | Straw Dog Box | NULL | 245.00 | | Pedal Medals | Chainsaw | 245.00 | 245.00 | | Randy Roofers | Sledge Hammer | 33.49 | 33.49 | +---------------+---------------------------------+----------------+-----------------------+
В този случай използвахме OVER
клауза с нашия SUM()
функция за разделяне на резултата по име на доставчик.
По този начин успяхме да върнем информация за цената за всеки продукт, както и сумата от всички продукти от този доставчик. Сумата се променя с промяната на доставчика (освен ако няколко доставчици имат една и съща сума), но остава една и съща за всички продукти от един и същ доставчик.
Тази концепция може да се приложи и към други агрегатни функции в SQL, като AVG()
, MIN()
, MAX()
и COUNT()
.