* Агрегатни функции
Публикувано на 17 март 2009 от Филип Петров. Записано в DB.
Преди да започнем, нека разгледаме следната база данни:
Ето и заявките за създаване на тази база данни и да вмъкнем произволни данни в нея:
CREATE DATABASE `banks`; CREATE TABLE `banks`.`banks` ( `code` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR( 255 ) NOT NULL , `country` VARCHAR( 255 ) NOT NULL , PRIMARY KEY ( `code` ) ) ENGINE = InnoDB; CREATE TABLE `banks`.`branches` ( `id` TINYINT NOT NULL AUTO_INCREMENT , `name` VARCHAR( 255 ) NOT NULL , `address` VARCHAR( 255 ) NOT NULL , `bank_code` INT NOT NULL , PRIMARY KEY ( `id` ) , FOREIGN KEY ( `bank_code` ) REFERENCES `banks`.`banks`( `code` ) ON DELETE CASCADE ) ENGINE = InnoDB; CREATE TABLE `banks`.`employees` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR( 255 ) NOT NULL , `branch_id` TINYINT NOT NULL, PRIMARY KEY ( `id` ), FOREIGN KEY ( `branch_id` ) REFERENCES `banks`.`branches`( `id` ) ON DELETE CASCADE ) ENGINE = InnoDB; CREATE TABLE `banks`.`customers` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR( 255 ) NOT NULL , `address` VARCHAR( 255 ) NULL DEFAULT NULL , `bank_mgr` INT NULL , PRIMARY KEY ( `id` ) , FOREIGN KEY ( `bank_mgr` ) REFERENCES `banks`.`employees`( `id` ) ) ENGINE = InnoDB; CREATE TABLE `banks`.`accounts` ( `id` INT NOT NULL AUTO_INCREMENT , `amount` DECIMAL( 9,2 ) NOT NULL , `type` TINYINT NOT NULL, `branch_id` TINYINT NOT NULL, `customer_id` INT NOT NULL, PRIMARY KEY ( `id` ), FOREIGN KEY ( `branch_id` ) REFERENCES `banks`.`branches`( `id` ) ON DELETE CASCADE, FOREIGN KEY ( `customer_id` ) REFERENCES `banks`.`customers`( `id` ) ON DELETE CASCADE ) ENGINE = InnoDB; USE banks; INSERT INTO `banks` (`code` ,`name` ,`country`) VALUES ( NULL , 'Bulbank', 'Bulgaria' ), ( NULL , 'Wells Fargo', 'USA' ), ( NULL , 'Bank of America', 'USA' ), ( NULL , 'Societe General', 'France' ); INSERT INTO `branches` (`id` ,`name` ,`address`, `bank_code`) VALUES ( NULL , 'Serdica', 'Sofia centar', 1 ), ( NULL , 'Slatina', 'Sofia Geo Milev', 1 ), ( NULL , 'Manhattan', 'Manhattan, New York', 2 ), ( NULL , 'LA', 'Los Angeles', 3 ), ( NULL , 'Paris', 'Paris', 4 ), ( NULL , 'Marseilles', 'Marseilles', 4 ); INSERT INTO `employees` (`id` ,`name` , `branch_id`) VALUES ( NULL , 'Ivan Ivanov', 1 ), ( NULL , 'Ivan Stoianov', 1 ), ( NULL , 'Mihail Zahariev', 1 ), ( NULL , 'Milen Stoilov', 2 ), ( NULL , 'Svilen Petrov', 2 ), ( NULL , 'Ilian Stoianov', 2 ), ( NULL , 'Petar Petrov', 2 ), ( NULL , 'Jimmy Carter', 3 ), ( NULL , 'John Smith', 3 ), ( NULL , 'Mary Jane', 3 ), ( NULL , 'James Pitt', 4 ), ( NULL , 'Francoa Dupres', 5 ), ( NULL , 'Alfonso Levi', 6 ); INSERT INTO `customers` (`id` ,`name` , `bank_mgr`) VALUES ( NULL , 'Todor Ivanov', 1 ), ( NULL , 'Petko Stoianov', 1 ), ( NULL , 'Neno Nenov', 2 ), ( NULL , 'Mariana Zaharieva', 3 ), ( NULL , 'Elica Zaharieva', 3 ), ( NULL , 'Atanas Petrov', 4 ), ( NULL , 'Ivan Ivanov', 4 ), ( NULL , 'Zlatomir Petrov', 4 ), ( NULL , 'Mihail Ivchev', 5 ), ( NULL , 'Todor Shtilianov', 6 ), ( NULL , 'Ivailo Ivanov', 7 ), ( NULL , 'George Lucas', 8 ), ( NULL , 'George Harison', 8 ), ( NULL , 'Michael Jackson', 8 ), ( NULL , 'Tony Martin', 8 ), ( NULL , 'Tony McCarter', 10 ), ( NULL , 'Alexander Smith', 11 ), ( NULL , 'Maria Smith', 11 ), ( NULL , 'Alain Delrick', 12 ), ( NULL , 'Devry Henry', 12 ), ( NULL , 'Lenard Renne', 12 ), ( NULL , 'Fontaine Rupert', 13 ); INSERT INTO `accounts` (`id` ,`amount` , `type` , `customer_id`, `branch_id`) VALUES ( NULL , 156.38, 2, 1, 1 ), ( NULL , 136.22, 1, 2, 1 ), ( NULL , 42.98, 1, 3, 1 ), ( NULL , 1236.33, 1, 4, 1 ), ( NULL , 211.98, 2, 5, 1 ), ( NULL , 1200.00, 2, 6, 2 ), ( NULL , 133.48, 1, 7, 2 ), ( NULL , 256.41, 2, 8, 2 ), ( NULL , 1331.50, 2, 9, 2 ), ( NULL , 116.88, 2, 10, 2 ), ( NULL , 200.91, 1, 10, 2 ), ( NULL , 99.18, 1, 11, 2 ), ( NULL , 6712.52, 1, 12, 3 ), ( NULL , 12000.56, 1, 12, 3 ), ( NULL , 322.99, 2, 12, 3 ), ( NULL , 991.63, 1, 13, 3 ), ( NULL , 559.32, 2, 14, 3 ), ( NULL , 680.13, 1, 15, 3 ), ( NULL , 532.57, 1, 15, 3 ), ( NULL , 402.26, 1, 16, 3 ), ( NULL , 1536.91, 2, 17, 4 ), ( NULL , 14921.43, 1, 18, 4 ), ( NULL , 3910.50, 1, 19, 5 ), ( NULL , 231.37, 1, 20, 5 ), ( NULL , 7236.60, 1, 21, 5 ), ( NULL , 2226.63, 2, 21, 5 ), ( NULL , 500.00, 2, 22, 6 );
Агрегатните функции ни позволяват да обединим (групираме) дадено множество и да направим някакво обобщение за него.
Ще ви дадем няколко прости примера:
1. Изкарайте броят на въведените банки в базата данни:
mysql> SELECT COUNT(*) FROM banks; +----------+ | COUNT(*) | +----------+ | 4 |
Функцията COUNT() в случая преброи броят редове на таблицата banks.
2. Изведете най-голямата сума на акаунт в базата данни:
mysql> SELECT MAX(amount) FROM accounts; +-------------+ | MAX(amount) | +-------------+ | 14921.43 | +-------------+
Функцията MAX() намери най-голямата стойност в колоната и я изведе на екрана.
3. Изведете най-малката сума на акаунт в базата данни от банков клон с id=2:
mysql> SELECT MIN(amount) FROM accounts WHERE branch_id=2; +-------------+ | MIN(amount) | +-------------+ | 99.18 | +-------------+
Очевидно MIN намери най-малката стойност в колоната „amount“ на таблица „accounts“.
4. Намерете средното аритметично на сумите на всички акаунти на Bulbank:
mysql> SELECT AVG(amount) FROM accounts WHERE branch_id IN( SELECT id FROM branches WHERE bank_code = ( SELECT code FROM banks WHERE name = 'Bulbank' ) ); +-------------+ | AVG(amount) | +-------------+ | 426.854167 | +-------------+ 1 row in set (0.00 sec)
Ясно е, че AVG() сумира стойностите в колоната по редове и разделя сумата на техния брой.
5. Изведете името и общата сума пари, която притежава клиент с id=12, във всички негови акаунти:
mysql> SELECT customers.name, SUM(accounts.amount) FROM customers JOIN accounts ON customers.id = accounts.customer_id WHERE customers.id = 12; +--------------+----------------------+ | name | SUM(accounts.amount) | +--------------+----------------------+ | George Lucas | 19036.07 | +--------------+----------------------+ 1 row in set (0.00 sec)
Функцията SUM() връща сумата на върнатите редове.
В следващата статия ще разгледаме една по-силна техника – групиране на таблици по дадена колона.
6 коментара за “Агрегатни функции”
Trackback URI | RSS за коментарите
Пусни коментар
Страници
Категории
- C/C++ (45)
- DB (36)
- Dogs (51)
- Food (8)
- History (9)
- Java (33)
- Lada (45)
- Math (104)
- Metodos (35)
- NetSec (36)
- Other (79)
- Politics (32)
- Probability (13)
- VC++.Net (1)
- XHTML/JS (25)
Нови
- Малко снимки от лятото…
- ASCII Лада Нива
- Анимация и обучение чрез забавление
- Активизиране на студентите по време на лекции
- Проблемно-ситуационно обучение

12 май 2010 на 18:09
Относно горната ER-диаграма, искам да ви попитам колко характеризиращи обекта може да има в една ER-диаграма и възможно ли е например account да е характеризиращ обект на customers?
12 май 2010 на 19:31
Да, може. Разликата между характеризиращ и обикновен обект практически не е никаква в реалното изпълнение на задачата. В общи линии се използват за пригледност.
07 септември 2010 на 13:55
Защо аccount e вързано и с branches, и с customer? Не трябва ли да е само с customer? И какво означава съкращението mgr?
07 септември 2010 на 15:26
Нарочно е направен този „двоен път“, за да бъдат демонстрирани някои проблеми с дизайна.
„mgr“ = „manager“ или „личен мениджър“ за този клиент.
07 септември 2010 на 15:40
А ако връзката с branches се прекъсне, ще бъде ли грешка?
07 септември 2010 на 16:36
Заявки 3. и 4. няма да работят. Ще трябва да се пренапишат. Впрочем ще е добро упражнение.