Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Сложные SQL запросы. Вложенные запросы, объединения, представления ⇐ ПредыдущаяСтр 8 из 8
Часто при выборке данных бывает необходимо объединить информацию из нескольких связанных таблиц. Сделать это можно посредством вложенных запросов, либо при помощи соединения с помощью SQL. Вложенные запросы В рамках нашего примера, допустим, что нам понадобилось узнать имена узлов, которые посещали сайт www.dom2.ru. Требуемую информацию можно получить запросом: SELECT hst_name FROM hosts WHERE hst_pcode IN (SELECT vis_hstcode FROM visits, sites WHERE (sit_pcode = vis_sitcode) AND (sit_name LIKE 'www.dom2.ru'));Рассмотрим этот запрос более пристально. Первый оператор SELECT нужен для выборки имен узлов. Чтобы выбрать требуемые нам имена, в запросе указана секция WHERE, в которой первичный ключ таблицы «Узлы» (hst_pcode) проверяется на принадлежность множеству (оператор IN). Судя по всему, множество для проверки на принадлежность должен вернуть второй оператор SELECT, находящийся в скобках. Рассмотрим его отдельно: SELECT vis_hstcode FROM visits, sites WHERE (sit_pcode = vis_sitcode) AND (sit_name LIKE 'www.dom2.ru')Для содержимого таблиц в нашем примере, вложенный запрос вернет следующее множество значений
Как видно из списка полей для выборки, запрос возвращает одно поле - vis_hstcode. Это коды узлов из таблицы «Посещения» (visits). Но после слова FROM указано две таблицы - visits и sites. Это нужно для удобства. Дело в том, что имена сайтов хранятся в таблице «Сайты» (sites), а в таблице «Посещения» - только идентификаторы сайтов. Таким образом, чтобы выбрать из таблицы «Посещения» данные только для сайта www.dom2.ru - мы связали две таблицы и указали в условии привычное для человека имя сайта. Подробнее о связывании речь пойдет чуть ниже. Таким образом, запрос, вернувший нам коды узлов будет являться вложенным запросом. Для содержимого таблиц в нашем примере, итоговый результат будет следующим
Соединение с помощью SQL Как и говорилось выше, одним из способов выборки данных из нескольких таблиц является соединение таблиц с помощью SQL. Основная цель такого соединения - создание нового отношения, которое будет содержать данные из двух или более исходных отношений. Внутреннее соединение Рассмотрим пример: SELECT hst_name, sit_name, vis_timestamp FROM hosts, visits, sites WHERE (hst_pcode = vis_hstcode) AND (vis_sitcode = sit_pcode)Данный запрос вернет следующие данные
В этом примере из трех таблиц (hosts, visits, sites) выбирается по одному полю и создается новая таблица, в которой будут собраны имена узлов, посещаемых сайтов и время посещений. Представление соединяемых данных регламентируется условиями в операторе WHERE. Видно, что имеется два условия, которые соединяют три таблицы. Поскольку в таблице посещений (visits) вместо имени узла и наименования сайта указаны их идентификаторы, при соединении таблиц мы добавляем условие, чтобы связать по идентификаторам данные и тогда все встанет на свои места. Если по каким-то причинам, вопреки ссылочной целостности в таблице посещений будут находиться записи с идентификатором несуществующего узла или сайта, они не появятся в результирующем наборе данных запроса в этом примере. Указанный выше пример немного упрощен и из-за немного упрощения теряется наглядность. Более наглядная форма запроса, соединяющего несколько таблиц и возвращающего тот же самый набор данных будет иметь вид SELECT hst_name, sit_name, vis_timestamp FROM hosts JOIN visits ON (hst_pcode = vis_hstcode) JOIN sites ON (vis_sitcode = sit_pcode);В запросе присутствует два оператора JOIN… ON. Поскольку «Join» можно перевести как «соединение» или «объединение», этот пример более красноречив. Если попытаться перевести текст SQL-запроса на русский, получится что-то вроде ВЫБРАТЬ (поля) hst_name, sit_name, vis_timestamp ИЗ (таблицы) hosts СОЕДИНИВ (с таблицей) visits ПО (условию) (hst_pcode = vis_hstcode) СОЕДИНИВ (с таблицей) sites ПО (условию) (vis_sitcode = sit_pcode);Русские слова в круглых скобках добавлены для облегчения понимания работы запроса. Вы можете использовать любой из вышеперечисленных способов написания запросов. Внешнее соединение Использованные выше способы соединения таблиц называются внутреннее соединение (inner join). У такого способа соединения есть недостатки. Например, если у нас не было посещений на один из сайтов, либо один из узлов не совершил ни одного посещения, то в результирующем наборе данных сайт или узел будут отсутствовать. В примере выше видно, что сайт www.yandex.ru отсутствует в данных, равно как и узел 1-3.Иногда это нежелательно и в таких случаях используют внешнее соединение (outer join). Внешнее соединение может быть левым (left join) и правым (right join). Сторона соединения (левая или правая) соответствует таблице, данные из которой будут выбираться полностью. Таким образом, при использовании LEFT JOIN, данные из таблицы слева от оператора JOIN будут выбираться полностью. Закрепим это примером. Допустим, надо выбрать ВСЕ узлы и связанные с ними посещения. Сделать это можно посредством запроса Обратите внимание на данные, которые вернутся в ответ на запрос
Видно, что узлу 1-3 не соответствует ни одно посещение, но он все равно в списке. Аналогичным образом работает RIGHT JOIN. Запрос, который вернет тот же набор данных можно записать с использованием RIGHT JOIN: SELECT hst_name, vis_timestamp FROM visits RIGHT JOIN hosts ON (hst_pcode = vis_hstcode);В этом случае, надо сменить LEFT JOIN на RIGHT JOIN и поменять местами таблицы visits и hosts в запросе. Использование UNION Иногда бывает нужно получить два списка записей из таблиц в виде одного. Для этой цели может быть использовано ключевое слово UNION, которое позволяет объединить результирующие наборы данных двух запросов в один набор данных. Допустим, надо получить некоторый список, в котором были бы узлы сети и имена сайтов. Таблицы разные, соответственно и запросы будут разными. Как объединить все в один набор данных? Легко, но есть определенные требования к такому «склеиванию» запросов: § запросы должны содержать одинаковое число полей; § типы данных полей объединяемых запросов так же должны совпадать. В остальном же, использование UNION не является сложным. Например, чтобы получить список имен узлов и имен сайтов в виде одного набора данных, выполним такой запрос: SELECT hst_name AS name FROM hosts UNIONSELECT sit_name AS name FROM sites;При таком подходе возможны проблемы с сортировкой записей. Чтобы список сайтов шел после списка узлов, можно умышленно добавить целочисленное поле, где указывать номер, который будет участвовать в сортировке. Например SELECT 1 AS level, hst_name AS name FROM hosts UNIONSELECT 2 AS level, sit_name AS name FROM sitesORDER BY level, name;Условия EXISTS и NOT EXISTS Иногда бывает необходимо выбрать из таблицы записи, которым соответствуют (или не соответствуют) записи в других таблицах. Допустим, что нам нужен список сайтов, на которые не было посещений. Получить такой список можно запросом SELECT sit_name FROM sites WHERE ((SELECT COUNT(*) FROM visits WHERE vis_sitcode = sit_pcode) = 0);Для нашего примера, список будет коротким:
Запрос работает следующим образом: § из таблицы sites выбирается код сайта и его наименование; § код сайта передается во вложенный запрос, который считает записи с этим кодом в таблице visits; § функция COUNT(*) сосчитает записи и вернет их количество, который будет передано в условие; § при истинности условия (количество записей равно 0) имя сайта добавляется в список. Если некоторым этот запрос покажется непонятным, то можно добиться тех же результатов посредством запроса с использованием NOT EXISTS: SELECT sit_name FROM sites WHERE NOT EXISTS (SELECT vis_pcode FROM visits WHERE vis_sitcode = sit_pcode);Выражение NOT EXISTS (на мой взгляд) вносит дополнительную ясность и более доступно для понимания. Аналогично работает выражение EXISTS, которое проверяет наличие записей. Представления (VIEW) Представления (VIEW) используются для обеспечения возможности сохранения сложного запроса на сервере под указанным именем. Допустим, вам часто приходится запрашивать данные, набирая объемный запрос. Если подойти к проблеме прогрессивно, то можно создать представление. Делается это несложно. Например, CREATE VIEW show_dom2 ASSELECT hst_name FROM hosts WHERE hst_pcode IN (SELECT vis_hstcode FROM visits, sites WHERE (sit_pcode = vis_sitcode) AND (sit_name LIKE 'www.dom2.ru'));Собственно, всё. Внимательный наблюдатель, наверное, заметил, что по-сути, можно взять запрос и в самом начале добавить слова «CREATE VIEW < имя> AS». Именно по такому принципу можно рекомендовать создание представлений. Создайте запрос, убедитесь в его работоспособности и потом допишите все необходимое, чтобы сохранить этот запрос на сервере как представление. Единственный недостаток использования представлений заключается в том, что некоторые особо сложные приемы написания запросов могут не работать в представлениях. К сожалению, в документации по postgreSQL очень мало сведений о представлениях и однозначно узнать, что можно использовать, а что нет вы сможете методом проб и ошибок. Сохранив запрос на сервере как представление, вы сможете выполнить его сколько угодно раз, запросом типа SELECT * FROM show_dom2;Важно отметить, что при выполнении запроса, который выбирает данные из представления - данные выбираются из таблиц посредством запроса, который хранится в представлении. Представление является полностью динамическим и данные, возвращаемые представлением будут актуальными при обновлении данных в таблицах. Удалить представление можно запросом типа DROP VIEW show_dom2;
Заключение данные отчет запрос заказ В данной курсовой работе была разработана база данных " Склад канцтоваров", содержащая всю необходимую информацию о товарах, покупателях, поставщиках и заказах. С помощью моей базы можно без затруднений и специальных знаний вести базу данных, которая позволяет делать все операции с клиентами, заказами, производителями. То есть добавлять, изменять, обновлять, удалять и просматривать все имеющиеся и вводимые данные. На основе базы данных были составлены запросы и отчеты.
ЗАКЛЮЧЕНИЕ
СПИСОК ЛИТЕРАТУРЫ
ПРИЛОЖЕНИЕ А
ПРИЛОЖЕНИЕ Б
ПРИЛОЖЕНИЕ В Популярное:
|
Последнее изменение этой страницы: 2016-06-05; Просмотров: 7168; Нарушение авторского права страницы