Реляционные базы данных определяют термин «функциональная зависимость» как таковой (из Википедии):
В теории реляционных баз данных функциональная зависимость — это ограничение между двумя наборами атрибутов в отношении из базы данных. Другими словами, функциональная зависимость — это ограничение, которое описывает отношение между атрибутами в отношении.
В SQL функциональные зависимости появляются всякий раз, когда существует уникальное ограничение (например, ограничение первичного ключа). Давайте предположим следующее:
|
1
2
3
4
5
|
CREATE TABLE actor ( actor_id BIGINT NOT NULL PRIMARY KEY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL); |
Можно сказать, что FIRST_NAME и LAST_NAME имеют функциональную зависимость от столбца ACTOR_ID .
Ницца. Ну и что?
Это не просто математическое утверждение, которое можно применить к уникальным ограничениям. Это чрезвычайно полезно для SQL. Это означает, что для каждого значения ACTOR_ID может быть только одно (функционально зависимое) значение FIRST_NAME и LAST_NAME . С другой стороны, это не так. Для любого заданного значения FIRST_NAME и / или LAST_NAME у нас может быть несколько значений ACTOR_ID , поскольку у нас может быть несколько действующих лиц с одинаковыми именами.
Поскольку для любого заданного значения ACTOR_ID может быть только одно соответствующее значение FIRST_NAME и LAST_NAME , мы можем опустить эти столбцы в предложении GROUP BY . Предположим также:
|
1
2
3
4
5
6
7
8
|
CREATE TABLE film_actor ( actor_id BIGINT NOT NULL, film_id BIGINT NOT NULL, PRIMARY KEY (actor_id, film_id), FOREIGN KEY (actor_id) REFERENCS actor (actor_id), FOREIGN KEY (film_id) REFERENCS film (film_id)); |
Теперь, если мы хотим посчитать количество фильмов на одного актера, мы можем написать:
|
1
2
3
4
5
6
|
SELECT actor_id, first_name, last_name, COUNT(*)FROM actorJOIN film_actor USING (actor_id)GROUP BY actor_idORDER BY COUNT(*) DESC |
Это чрезвычайно полезно, так как избавляет нас от большого количества печатания. Фактически, как определяется семантика GROUP BY , мы можем поместить всевозможные ссылки на столбцы в предложении SELECT , которые являются следующими:
- Выражения столбцов, которые появляются в предложении
GROUP BY - Выражения столбцов, которые функционально зависят от набора выражений столбцов в предложении
GROUP BY - Агрегатные функции
К сожалению, не все это поддерживают
Например, если вы используете Oracle, вы не можете использовать вышеперечисленное. Вам нужно написать классическую эквивалентную версию, в которой все неагрегированные выражения столбцов, появляющиеся в предложении SELECT , также должны появляться в предложении GROUP BY
|
1
2
3
4
5
6
7
|
SELECT actor_id, first_name, last_name, COUNT(*)FROM actorJOIN film_actor USING (actor_id)GROUP BY actor_id, first_name, last_name-- ^^^^^^^^^^ ^^^^^^^^^ unnecessaryORDER BY COUNT(*) DESC |
Дальнейшее чтение:
- Статья в Википедии о функциональной зависимости
- Как должен был быть разработан SQL GROUP BY — как неявный GROUP BY в Neo4j
- Вы действительно понимаете SQL-предложения GROUP BY и HAVING?
- Как перевести SQL GROUP BY и агрегаты в Java 8
- GROUP BY ROLLUP / CUBE
| Ссылка: | SQL GROUP BY и функциональные зависимости: очень полезная функция от нашего партнера по JCG Лукаса Эдера из блога JAVA, SQL и AND JOOQ . |