Раздел 2: Запросы на выборку и модификацию данных
Раздел 2: Запросы на выборку и модификацию данных
2.1. Выборка из одной таблицы
2.1.1. Пример 1: выборка всех данных
Задача 2.1.1.a{17}: показать всю информацию обо всех читателях.
|
Ожидаемый результат 2.1.1.a. |
|
|
|
|
s_id |
s_name |
|
1 |
Иванов И.И. |
|
2 |
Петров П.П. |
|
3 |
Сидоров С.С. |
|
4 |
Сидоров С.С. |
|
'IT Решение 2.1.1 .a{17}.
В данном случае достаточно самого простого запроса — классического SE- LECT *. Для всех трёх СУБД запросы совершенно одинаковы.
Задание 2.1.1.TSK.A: показать всю информацию:
•об авторах;
•о жанрах.
Работа с MySQL, MS SQL Server и Oracle в примерах © Богдан Марчук Стр: 20/545
Пример 2: выборка данных без повторения
2.1.2. Пример 2: выборка данных без повторения
Задача 2.1.2.a{18}: показать без повторений идентификаторы читателей, бравших в библиотеке книги.
Задача 2.1.2. b{19}: показать поимённый список читателей с указанием количества полных тёзок по каждому имени.
Ожидаемый результат 2.1.2.a.
sb_subscriber
1
|
3 |
______ |
|
|
|
|
4 |
|
|
|
|
|
|
Ожидаемый результат 2.1.2.b. |
|
|
|
|
|
|
|
|
|
|
|
|
s_name |
people_count |
|
|
|
|
Иванов И.И. |
1 |
|
|
|
|
Петров П.П. |
1 |
|
|
|
|
Сидоров С.С. |
2 |
|
уЦ7
А/1- Решение 2.1.2. a{18}.
Р ^<4
Важным для получения правильного результата является использование ключевого слова DISTINCT, которое предписывает СУБД убрать из результирующей выборки все повторения.
Если ключевое слово DISTINCT удалить из запроса, результат выполнения будет таким (поскольку читатели брали книги по несколько раз каждый):
sb_subscriber
1
1
1
1
1
3
3
3
4
4
4
Работа с MySQL, MS SQL Server и Oracle в примерах © Богдан Марчук Стр: 21/545
Пример 2: выборка данных без повторения
Важно понимать, что СУБД в DiSTiNCT-режиме выполнения запроса производит сравнение между собой не отдельных полей, а строк целиком, а потому, если хотя бы в одном поле между строками есть различие, строки не считаются идентичными.
Типичная ошибка — попытка использовать DISTINCT «как функцию». До-
пустим, мы хотим увидеть без повторений все имена читателей (напомним, «Сидоров С.С.» у нас встречается дважды), выбрав не только имя, но и
идентификатор. Следующий запрос составлен неверно.
В результате выполнения такого запроса мы получим результат, в котором «Сидоров С.С.» представлен дважды (дублирование не устранено) из-за того, что у этих записей разные идентификаторы (3 и 4), которые и не позволяют СУБД посчитать две соответствующие строки выборки совпадающими. Результат выполнения запроса 2.1.2.ERR.A будет таким:
s_name |
s_id |
Иванов И.И. |
1 |
Петров П.П. |
2 |
Сидоров С.С. |
3 |
Сидоров С.С. |
4 |
Частый вопрос: а как тогда решить эту задачу, как показать записи без повторения строк, в которых есть поля с различными значениями? В общем случае никак, т.к. сама постановка задачи неверна (мы просто потеряем часть данных).
Если задачу сформулировать несколько иначе (например, «показать поимённый список читателей с указанием количества полных тёзок по каждому имени»), то нам помогут группировки и агрегирующие функции. Подробно мы рассмотрим этот вопрос далее (см. пример 10{61}), а пока решим только что упомянутую задачу, чтобы показать разницу в работе запросов.
ЧРешение 2.1.2. b{18}.
Используем конструкцию GROUP BY для группировки рядов выборки и функцию COUNT для подсчёта количества записей в каждой группе.
MySQL і Решение 2.1.2.b [
1SELECT 'sjname',
2COUNT(*) AS 'people_count'
3 |
FROM |
'subscribers' |
4 |
GROUP |
BY 's name' |
Работа с MySQL, MS SQL Server и Oracle в примерах © Богдан Марчук Стр: 22/545
Пример 2: выборка данных без повторения
MS SQL і Решение 2.1.2.b |
[ |
||
. 1 |
... SELECT . [s^nameT, ........................................................... |
||
2 |
|
COUNT(*) AS [people_count] |
|
|
FROM [subscribers] |
||
|
GROUP BY [s name] |
||
Oracle і Решение 2.1.2.b |
[ |
||
1 .. |
SELECT . "s^name"'?* ......................................................... |
||
2 |
|
COUNT(*) AS "people_count" |
|
|
FROM |
"subscribers" |
|
|
GROUP |
BY "s name" |
|
Агрегирующая функция COUNT(*) (представленная во второй строке всех
запросов 2.1.2.b) производит подсчёт записей, сгруппированных по совпадению значения поля s_name (см. четвёртую строку в запросах 2.1.2.b).
Для быстрого понимания логики группировок можно использовать аналогию с объединением ячеек с одинаковыми значениями в таблице Word или Excel, после чего происходит анализ (чаще всего — подсчёт или суммирование) ячеек, соответствующих каждой такой «объединённой ячейке». В только что рассмотренном примере 2.1.2. b эту аналогию можно выразить следующим образом:
s_id s_name
1Иванов И.И.
2Петров П.П.
3 |
Сидоров С.С. |
|
4 |
||
|
Теперь СУБД считает строки таблицы в контексте выполненной группировки, и получает, что Иванова и Петрова у нас по одному человеку, а Сидоровых — два, что и отражено в ожидаемом результате 2.1.2.b.
Задание 2.1.2.TSK.A: показать без повторений идентификаторы книг, которые были взяты читателями.
Задание 2.1.2.TSK.B: показать по каждой книге, которую читатели брали в библиотеке, количество выдач этой книги читателям.
Работа с MySQL, MS SQL Server и Oracle в примерах © Богдан Марчук Стр: 23/545
Пример 3: использование функции COUNT и оценка её производительности
2.1.3.Пример 3: использование функции COUNT и оценка её производительности
Задача 2.1.3.a{21}: показать, сколько всего разных книг зарегистрировано в библиотеке.
Ожидаемый результат 2.1.3.a.
total_books
7
уЦ7
ЧР Решение 2.1.3.a{21}.
Если переформулировать задачу, она будет звучать как «показать, сколько всего записей есть в таблице books», и решение выглядит так.
Функция COUNT может быть использована в следующих пяти форматах:
•COUNT(*) — классический вариант, используемый для подсчёта количества записей;
•COUNT(1) — альтернативная запись классического варианта;
•сошт(первичный_ключ) — альтернативная запись классического варианта;
•сошт(поле) — подсчёт записей, в указанном поле которых нет NULL- значений;
•COUNT(DISTINCT поле) — подсчёт без повторения записей, в указанном поле которых нет NULL-значений.
Одним из самых частых вопросов относительно разных вариантов COUNT является вопрос о производительности: какой вариант работает быстрее?
Исследование 2.1.3. EXP.A: оценка скорости работы различных вариантов COUNT в зависимости от объёма обрабатываемых данных. Это иссле-
дование — единственное, в котором кэш СУБД не будет сбрасываться перед выполнением каждого следующего запроса.
В базе данных «Исследование» создадим таблицу test_counts, содержащую такие поля:
•id — автоинкрементируемый первичный ключ (число);
•fni — поле без индекса («field, no index») (число или NULL);
•fwi — поле с индексом («field, with index») (число или NULL);
•fni_nn — поле без индекса и NULL^B («field, no index, no nulls») (число);
Работа с MySQL, MS SQL Server и Oracle в примерах © Богдан Марчук Стр: 24/545