Есть вопрос?
Зайди на форум

Поиск на сайте: Advanced

Denix - новый дистрибутив Linux. Русификация Ubuntu и установка кодеков

dkws.org.ua
Форум сайта dkws.org.ua
 
Главная    ТемыТемы    АльбомАльбом    РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

Сложные запросы в MySQL

 
Начать новую тему Ответить на тему    Список форумов dkws.org.ua -> Базы данных
 
Автор Сообщение
den

Старожил


Зарегистрирован: 31.01.2006
Сообщения: 13742
Откуда: Кировоград, Украина

СообщениеДобавлено: Пт Апр 03, 2009 5:30 am    Заголовок сообщения: Сложные запросы в MySQL
Ответить с цитатой

Использование объединений для запросов к нескольким таблицам
В предыдущей статье (Простые запросы MySQL) мы рассмотрели запросы, которые возвращают данные только из одной таблицы. В условиях нормализованной базы данных, когда информация хранится не в одной, а в большем количестве таблиц, возникает необходимость выбора из нескольких таблиц. Хорошо спроектированная реляционная база данных становится удобной из-за связей между таблицами. При выборе информации из нескольких таблиц такие связи называют объединениями. А теперь рассмотрим запросы, в которых объединяются несколько таблиц.
Объединение двух таблиц
Рассмотрим следующий запрос:
SELECT test_table.name, test_table2.name
FROM test_table, test_table2
WHERE test_table.id=test_table2.id
Здесь в выражении FROM вместо одной таблицы указаны две.
Сначала мы выбрали столбцы, принадлежащие двум разным таблицам. (Как видите, мы применили запись, использующую, точку-разделитель, чтобы различить поле name из таблицы test_table и поле name из таблицы test_table2) Для этого потребовалось включить обе таблицы в выражение FROM. Наиболее интересным в этом запросе является выражение WHERE. Если выполнить подобный запрос без выражения WHERE,
SELECT test_table.name, test_table2.name
FROM test_table, test_table2
В данном запросе мы получим результирующее множество всех возможных комбинаций полей из обеих таблиц.
Ясно, что выражение WHERE важно с точки зрения получения нужного нам результата. Набор условий, используемых при создании связи для объединения таблиц, называют условием объединения. В данном случае мы использовали условие test_table.id=test_table2.id, которое связывает таблицы по внешним ключам.
Когда требуется извлечь информацию сразу из нескольких таблиц, для нахождения этой информации приходится использовать имеющиеся между таблицами связи. Иногда это означает необходимость найти путь от уже имеющейся информации к информации, нужной вам. Для того, что бы максимально упростить данный процесс необходимо уделить больше внимания проектированию базы данных.
Еще одним важным моментом является то, что в двух предыдущих наборах результатов оба столбца имеют заголовки name, поскольку именно так они названы в соответствующих таблицах. С помощью псевдонимов можно было бы улучшить представление результата, например, так:
SELECT test_table.name as Test_table.Name, test_table2.name as Name_2
FROM test_table, test_table2
WHERE test_table.id=test_table2.id
В данном примере естественно и названия таблиц и псевдонимы столбцов условны. Но в реальной жизни, при построении сложных запросов объединяющих несколько таблиц данных использование псевдонимов зачастую единственный вариант различить, где какие именно данные определены.
Объединение нескольких таблиц
Объединение нескольких таблиц аналогично объединению двух таблиц.
Допустим, мы знаем имя клиента, и, найдя его в таблице клиентов, можно выяснить его кодовый номер (client_id). Это можно использовать для того, чтобы найти соответствующие задания в таблице заданий и увидеть, какие работники работали с данным клиентом. Из таблицы заданий мы получим кодовые номера работников (id), а по таблице сотрудников можно выяснить номера отделов, в которых эти служащие работают. С этой информацией мы можем обратиться к таблице отделов и найти название соответствующего отдела!
Создание подзапросов
Подзапрос - это запрос внутри другого запроса, т.е. запрос, в котором используются результаты другого запроса. Иногда подзапросы называют вложенными запросами или подвыборками. Подзапросы не добавляют новых функциональных возможностей, но с ними запросы часто оказываются более удобными для чтения, чем со сложными наборами условий объединения.
Подзапросы очень мощное средство работы с базой данных SQL, но должен отметить, что подзапросы заметно снижают безопасность WEB-приложений. Но здесь возникает ситуация, что даже если Вы их не используете сами, они могут быть использованы против Вас, так как входят в структуру языка.(Начиная с версии СУБД 4).
Вы уже видели, как применяются подзапросы, хотя мы и не акцентировали на этом внимание. Многотабличные удаления и обновления, о которых говорилось в статье "Вставка, удаление и обновление данных", являются одним из специальных видов подзапросов.
В этой статье мы рассмотрим подзапросы в операторах SELECT. В MySQL были добавлены два основных вида подзапросов:
подзапросы производных таблиц;
подзапросы-выражения.
Подзапросы-выражения применяются в выражении WHERE оператора SELECT,
Они бывают двух типов:
подзапросы, возвращающие одно значение или строку;
подзапросы, используемые в логическом выражении.
Мы рассмотрим примеры подзапросов обоих указанных типов.
Подзапросы производных таблиц
Подзапросы производных таблиц дают возможность указать запрос в выражении FROM другого запроса. По сути это позволяет создать временную таблицу и добавить ее в запрос. Например, рассмотрим следующий простой запрос:
SELECT id, name FROM test WHERE job='Программист';
Должно быть очевидным, что этот запрос возвратит имена и кодовые номера всех программистов. Можно использовать этот запрос в рамках другого, чтобы получить дополнительную информацию:
SELECT programmer.name
FROM (SELECT id, name FROM test
WHERE jоb='Программист')
as programmer,
assignment
WHERE programmer.id = assignment.id;

в данном случае мы используем подзапрос (SELECT id, name FROM test WHERE job='Программист') для создания производной таблицы, содержащей только id и name, которой мы назначаем псевдоним programmer. После этого к созданной таблице можно обратиться с запросом, как к любой другой. В данном случае мы используем эту таблицу для того, чтобы выяснить, кто из программистов работал над выполнением внешних заданий.
Подзапросы с ОДНИМ значением
Как и в предыдущем разделе, мы начинаем с простого запроса SELECT max(hours) FROM test;
Он возвращает одно значение, представляющее собой максимальное время (в часах), которое работник потратил на выполнение задания. Здесь используется функция MySQL, которую мы не еще упоминали, - функция mах ( ) , возвращающая максимальное значение соответствующего столбца. (Мы обсудим функцию mах () более подробно в следующей статье.) Использование результатов, возвращенных такими функциями, является типичным примером применения подзапросов с одним значением.
Можно пойти дальше и использовать данный запрос в рамках другого. Подзапросы с одним значением возвращают одно значение столбца и обычно используются для сравнения.
Подзапросы в логических выражениях
Подзапросы в логических выражениях используются для проверки истинности результата некоторых специальных функций, возвращающих значения типа BOOLEAN. Такими специальными функциями являются IN, EXISTS, а также ALL, ANY и SOME.
Ключевое слово IN используется для проверки принадлежности к некоторому множеству значений. Рассмотрим следующий запрос:
SELECT name
FROM test
WHERE id NOT IN
(SELECT id
FROM assignment);

Этот запрос даст тот же результат, что и запрос, рассмотренный выше в примере применения LEFT JOIN. Он позволяет найти работников, которые не имели внешних заданий. Ключевое слово IN позволяет провести поиск в некотором множестве значений.
Достаточно интересным является следующая возможность использования ключевого слова IN для проверки принадлежности к определенному набору значений:
SELECT name
FROM test
WHERE id NOT IN (6651, 1234);
Ключевое слово EXISTS работает лишь немного по-другому по сравнению со словом IN. При использовании EXISTS мы на самом деле используем в подзапросе данные некоторого внешнего запроса. Такой запрос иногда называют связанным подзапросом.
Ключевые слова ALL, ANY и SOME используются для сравнения с набором значений, возвращенных подзапросом.
Опции оператора SELECT
Знакомясь с оператором SELECT, мы рассмотрели сокращенную форму общего синтаксиса этого оператора. Теперь рассмотрим полный синтаксис оператора и выясним, что нам уже известно.
Согласно руководству по MySQL, оператор SELECT имеет следующую форму:
SELECT [STRAIGHT JOIN]
[SQL_SМALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE I SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH PRIORITY] [DISTINCT I DISTINCTROW I ALL] выражение_select, . . .
[INTO {OUTFILE I DUMPFILE} 'имя-файла' опции-экспорта] [FROM таблицы-ссылки
[WHERE определение_where]
[GROUP ВУ {целое_без_знака , имя-столбца , формула}
[ASC I DESC], ...]
[HAVING групповые-условия]
[ORDER ВУ {целое_без_знака , имя-столбца , формула}
[ASC I DESC], . ..]
[LIMIT [смещение,] строки , строки OFFSET смещение] [PROCEDURE имя_процедуры(список_аргументов)]
[FOR UPDATE I LOCK IN SHARE МООЕ]]
Большинство из указанных выражений нам уже знакомо. А теперь вкратце рассмотрим те из них, которые мы еще не обсуждали.
Выражение STRAIGHT JOIN в начале оператора может использоваться для того, чтобы заставить оптимизатор запроса объединять таблицы так, как указали вы. Это будет иметь тот же эффект, что и указание STRAIGHT JOIN в выражении WHERE, как было сделано в рассмотренном выше примере.
Опции SQL_SMALL_RESULT,SQL_BIG_RESULT и SQL_BUFFER_RESULT предназначены для настройки параметров оптимизации.
SQL _ SMALL_RESULT и SQL_BIG_RESULT сообщают MySQL, что вы ожидаете увидеть в результирующем множестве либо всего несколько строк, либо большое их число.
S Q L _BUFFER_RESULT говорит MySQL о том, что результат следует поместить во временную таблицу. Этим способом можно воспользоваться тогда, когда обработка данных занимает значительное время, чтобы отправить результаты клиенту, не допуская блокирования соответствующей таблицы в это время. Эти опции являются расширениями MySQL.
SQL_САСНЕ и SQL _NOCACHE сообщают MySQL, следует ли кэшировать результаты. (Еще одно расширение MySQL.)
SQL _CALC _FOUND_ROWS предполагается использовать с выражением LIMIT. Эта опция заставляет MySQL выяснить, сколько строк должно возвратиться в случае отсутствия выражения LIMIT. Это значение тогда можно выяснить с помощью SELECT FOUND - rows () (еще одно расширение MySQL). Опция имеет своей целью минимум дублирования действий. В версиях без этой возможности обычным решением оказывается выполнение сначала запроса с функцией COUNT (*), а затем - оператора SELECT с выражением LIMIT.
HIGH PRIORITY сообщает MySQL о том, что запрос должен иметь указанный приоритет в сравнении со всеми операторами UPDATE, ожидающими доступа к используемым таблицам.
Мы уже говорили о ключевом слове DISTINCT, а DISTINCTROW является его синонимом. ALL является антонимом (возвращает все повторения) и используется по умолчанию.
Команда SELECT INTO OUTFILE противоположна команде LOAD DATA INFILE, рассмотренной в статье, "Вставка, удаление и обновление данных". Эта команда помещает возвращаемый оператором SELECT результат в заданный файл. Параметры опции экспорта аналогичны опциям выражения LOAD DATA INFILE.
Команда PROCEDURE позволяет указать процедуру, которую следует применить к результирующему множеству перед тем, как оно будет отправлено клиенту. Эта процедура должна быть написана на языке С++. Написание данных процедур я здесь не рассматриваю, но стоит наверное иметь в виду такую возможность.
Выражения FOR UPDATE и LOCK IN SHARE MODE могут понадобиться только тогда, когда механизм хранения использует блокировку на уровне страниц или строк - на практике это означает работу с InnoDB и BDB. Если указать FOR UPDATE, устанавливается блокировка с монополизацией, а если указать LOCK IN SHARE MODE, устанавливается блокировка с обеспечением совместного доступа. Мы обсудим различные типы блокировки в одной из следующих статей.

Оригинал kamaikin.ru/artical/sql/1/22/
Вернуться к началу
Посмотреть профиль Отправить личное сообщение dhsilabs@jabber.ru
Показать сообщения:   
Начать новую тему Ответить на тему    Список форумов dkws.org.ua -> Базы данных Часовой пояс: GMT
Страница 1 из 1
 Главная страница сайта
 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
© Колисниченко Денис