Database Programming & Design




Раздел GROUP BY


В качестве основы примеров используется известная по книгам К. Дейта база данных "поставщики и детали":

S ( S#, SNAME, STATUS, CITY ) PRIMARY KEY ( S# )

P ( P#, PNAME, COLOR, WEIGHT, CITY ) PRIMARY KEY ( P# )

SP ( S#, P#, QTY ) PRIMARY KEY ( S#, P# ) FOREIGN KEY ( S#) REFERENCES S FOREIGN KEY ( P#) REFERENCES P

Вот запрос к этой базе данных, для которой люди "естественно" используют раздел GROUP BY:

Q1: Для каждой поставляемой детали выдать номер детали, максимальное и минимальное число поставок.

"Естественной" (с применением GROUP BY) формулировкой запрса является следующая:

SELECT SP.P#, MAX(SP.QTY) AS MXQ, MIN(SP.QTY) AS MNQ FROM SP GROUP BY SP.P# ;

Предположим, что база данных содержит следующие значения:

S SP

S# SNAME STATUS CITY S# P# QTY ------------------------------- -------------- S1 SMITH 20 LONDON S1 P1 300 S2 JONES 10 PARIS S1 P2 200 S3 BLAKE 30 PARIS S1 P3 400 S4 CLARK 20 LONDON S1 P4 200 S5 ADAMS 30 ATHENS S1 P5 100 S1 P6 100 P S2 P1 300 S2 P2 400 P# PNAME COLOR WEIGHT CITY S3 P2 200 ------------------------------------ S4 P2 200 P1 Nut Red 12 London S4 P4 300 P2 Bolt Green 17 Paris S4 P5 400 P3 Screw Blue 17 Rome P4 Screw Red 14 London P5 Cam Blue 12 Paris P6 Cog Red 19 Rome

Тогда результатом запроса будет следующая таблица:

P# MXQ MNQ --------------- P1 300 300 P2 400 200 P3 400 400 P4 300 200 P5 400 100 P6 100 100

Вот другая формулировка того же самого запроса без использования GROUP BY:

SELECT DISTINCT SP.P#, (SELECT MAX(SPX.QTY) FROM SP AS SPX WHERE SPX.P# = SP.P#) AS MXQ, (SELECT MIN(SPX.QTY) FROM SP AS SPX WHERE SPX.P# = SP.P#) AS MXQ FROM SP ;

Конечно, эта формулировка немного дленнее предыдущей, но логически они эквивалентны. Обобщая этот пример, можно вывести следующее заключение:

Пусть имеется таблица R { A, B, ... } и пусть agg - это агрегатная функция (например, SUM, MAX или MIN), применимая к столбцу R.B. Тогда выражение

SELECT R.A, agg(R.B) AS C FROM R GROUP BY R.A ;




Содержание  Назад  Вперед