Понимание SQL (775646), страница 20
Текст из файла (страница 20)
ГРУППОВЫЕ ПРЕДСТАВЛЕНИЯ
Групповые представления - это представления, наподобие запроса Ratingcount в предыдущем примере, который содержит предложение GROUP BY, или который основывается на других групповых представлениях.
Групповые представления могут стать превосходным способом обрабатывать полученную информацию непрерывно. Предположим, что каждый день вы должны следить за порядком номеров заказчиков, номерами продавцов принимающих порядки, номерами порядков, средним от порядков, и общей суммой приобретений в порядках.
Чем конструировать каждый раз сложный запрос, вы можете просто создать следующее представление:
CREATE VIEW Totalforday
AS SELECT odate, COUNT (DISTINCT cnum), COUNT
(DISTINCT snum), COUNT (onum), AVG
(amt), SUM (amt)
FROM Orders
GROUP BY odate;
Теперь вы сможете увидеть всю эту информацию с помощью простого запроса:
SELECT *
FROM Totalforday;
Как мы видели, SQL запросы могут дать вам полный комплекс возможностей, так что представления обеспечивают вас чрезвычайно гибким и мощным инструментом чтобы определить точно, как ваши данные могут быть использованы.
Они могут также делать вашу работу более простой, переформатируя данные удобным для вас способом и исключив двойную работу.
ПРЕДСТАВЛЕНИЯ И ОБЪЕДИНЕНИЯ
Представления не требуют чтобы их вывод осуществлялся из одной базовой таблицы. Так как почти любой допустимый запрос SQL может быть использован в представлении, он может выводить информацию из любого числа базовых таблиц, или из других представлений.
Мы можем, например, создать представление которое показывало бы, порядки продавца и заказчика по имени:
CREATE VIEW Nameorders
AS SELECT onum, amt, a.snum, sname, cname
FROM Orders a, Customers b, Salespeople c
WHERE a.cnum = b.cnum
AND a.snum = c.snum;
Теперь вы можете выбрать (SELECT) все порядки заказчика или продавца (*), или можете увидеть эту информацию для любого порядка.
Например, чтобы увидеть все порядки продавца Rifkin, вы должны ввести следующий запрос (вывод показан в 20.3 Рисунке):
SELECT *
FROM Nameorders
WHERE sname = 'Rifkin';
=============== SQL Execution Log ==============
| |
| SELECT * |
| FROM Nameorders |
| WHERE sname = 'Rifkin'; |
| =============================================== |
| onum amt snum sname cname |
| ------ -------- ----- ------- ------- |
| 3001 18.69 1007 Rifkin Cisneros |
| 3006 1098.16 1007 Rifkin Cisneros |
| |
================================================
Рисунок 20.3: Порядки Rifkin показанные в Nameorders
Вы можете также объединять представления с другими таблицами, или базовыми таблицами или представлениями, поэтому вы можете увидеть все порядки Axelrodа и значения его комиссионных в каждом порядке:
SELECT a.sname, cname, amt comm
FROM Nameorders a, Salespeople b
WHERE a.sname = 'Axelrod'
AND b.snum = a.snum;
Вывод для этого запроса показывается в Рисунке 20.4.
В предикате, мы могли бы написать - " WHERE a.sname = ’Axelrod' AND b.sname = ’Axelrod’ " , но предикат который мы использовали здесь более общеупотребительный. Кроме того поле snum - это первичный ключ таблицы Продавцов, и следовательно должен по определению быть уникальным.
=============== SQL Execution Log ==============
| |
| SELECT a.sname, cname, amt * comm |
| FROM Nameorders a, Salespeople b |
| WHERE a.sname = 'Axelrod' |
| AND b.snum = a.snum; |
| =============================================== |
| onum amt snum sname cname |
| ------ -------- ----- ------- ------- |
| 3001 18.69 1007 Rifkin Cisneros |
| 3006 1098.16 1007 Rifkin Cisneros |
| |
================================================
Рисунок 20. 4: Объединение основной таблицы с представлением
Если бы там например было два Axelrodf, вариант с именем, будет объединять вместе их данные. Более предпочтительный вариант - использовать поле snum чтобы хранить его отдельно.
ПРЕДСТАВЛЕНИЯ И ПОДЗАПРОСЫ
Представления могут также использовать и подзапросы, включая соотнесенные подзапросы. Предположим ваша компания предусматривает премию для тех продавцов которые имеют заказчика с самым высоким порядком для любой указанной даты. Вы можете проследить эту информацию с помощью представления:
CREATE VIEW Elitesalesforce
AS SELECT b.odate, a.snum, a.sname,
FROM Salespeople a, Orders b
WHERE a.snum = b.snum
AND b.amt =
(SELECT MAX (amt)
FROM Orders c
WHERE c.odate = b.odate);
Если, с другой стороны, премия будет назначаться только продавцу который имел самый высокий порядок за последние десять лет, вам необходимо будет проследить их в другом представлении основанном на первом:
CREATE VIEW Bonus
AS SELECT DISTINCT snum, sname
FROM Elitesalesforce a
WHERE 10 < =
(SELECT COUNT (*)
FROM Elitesalestorce b
WHERE a.snum = b.snum);
Извлечение из этой таблицы продавца, который будет получать премию - выполняется простым вопросом:
SELECT *
FROM Bonus;
Теперь мы видим истинную мощность SQL. Извлечение той же полученной информации программами RPG или COBOL будет более длительной процедурой. В SQL, это - только вопрос из двух комплексных команд, сохраненных, как представление совместно с простым запросом.
При самостоятельном запросе - мы должны заботится об этом каждый день, потому что информация которую извлекает запрос, непрерывно меняется чтобы отражать текущее состояние базы данных.
ЧТО НЕ МОГУТ ДЕЛАТЬ ПРЕДСТАВЛЕНИЯ
Имеются большое количество типов представлений (включая многие из наших примеров в этой главе) которые являются доступными только для чтения. Это означает, что их можно запрашивать, но они не могут подвергаться действиям команд модификации.
(Мы будем рассматривать эту тему в Главе 21.)
Имеются также некоторые виды запросов, которые не допустимы в определениях представлений. Одиночное представление должно основываться на одиночном запросе; ОБЪЕДИНЕНИЕ (UNION) и ОБЪЕДИНЕНИЕ
ВСЕГО (UNION ALL) не разрешаются.
УПОРЯДОЧЕНИЕ ПО(ORDER BY) никогда не используется в определении представлений.
Вывод запроса формирует содержание представления, которое напоминает базовую таблицу и является - по определению - неупорядоченным.
УДАЛЕНИЕ ПРЕДСТАВЛЕНИЙ
Синтаксис удаления представления из базы данных подобен синтаксису удаления базовых таблиц:
DROP VIEW
В этом нет необходимости, однако, сначала надо удалить все содержание как это делается с базовой таблицей, потому что содержание представления не является созданным и сохраняется в течении определенной команды. Базовая таблица из которой представление выводится, не эффективна когда представление удалено.
Помните, вы должны являться владельцем представления чтобы иметь возможность удалить его.
РЕЗЮМЕ
Теперь, когда вы можете использовать представления, ваша способность отслеживать и обрабатывать содержание вашей базы данных, значительно расширилась. Любые вещи которые вы можете создать с запросом, вы всегда сможете определить как представление. Запросы этих представлений, фактически, запрос запроса.
Использование представлений и для удобства и для защиты, также удобно как и многие возможности представлений для форматирования и получения значений из постоянно меняющегося содержания вашей базы данных. Имеется один главный вывод относительно представлений, это способность к модификации, которую мы выбрали в отличии от Главы 21. Как показано, вы можете модифицировать представления также как и базовую таблицу, с помощью изменений применяемых к таблице из которой получается представление, но это не всегда возможно.
РАБОТА С SQL
1. Создайте представление которое бы показывало всех заказчиков которые имеют самые высокие оценки.
2. Создайте представление которое бы показывало номер продавца в каждом городе.
3. Создайте представление которое бы показывало усредненный и общий порядки для каждого продавца после его имени. Предполагается, что все имена - уникальны.
4. Создайте представление которое бы показывало каждого продавца с многочисленными заказчиками.
(См. Приложение A для ответов.)
21. ИЗМЕНЕНИЕ ЗНАЧЕНИЙ С ПОМОЩЬЮ ПРЕДСТАВЛЕНИЙ
Эта глава рассказывает о командах модификации языка DML - ВСТАВИТЬ(INSERT), ИЗМЕНИТЬ(UPDATE), и УДАЛИТЬ(DELETE) - когда они применяются для представлений. Как упомянуто в предыдущей главе, использование команд модификации в представлениях - это косвенный способ использования их в ссылочных таблицах с помощью запросов представлений. Однако, не все представления могут модифицироваться.
В этой главе, мы будем обсуждать правила определяющие, является ли представление модифицируемым. Кроме того, вы обучитесь использованию предложения WITH CHECK OPTION, которое управляет указанными значениями, которые можно вводить в таблицу с помощью представления. Как упомянуто в Главе 18, это, в некоторых случаях, может быть желательным вариантом непосредственного ограничения таблицы.
МОДИФИЦИРОВАНИЕ ПРЕДСТАВЛЕНИЯ
Один из наиболее трудных и неоднозначных аспектов представлений непосредственное их использование с командами модификации DML.
Как упомянуто в предыдущей главе, эти команды фактически воздействуют на значения в базовой таблице представления.
Это является некоторым противоречием. Представление состоит из результатов запроса, и когда вы модифицируете представление, вы модифицируете набор результатов запроса. Но модификация не должна воздействовать на запрос ; она должна воздействовать на значения в таблице к которой был сделан запрос, и таким образом изменять вывод запроса. Это не простой вопрос. Следующий оператор будет создавать представление показанное на Рисунке 21.1:
CREATE VIEW Citymatch (custcity, salescity)
AS SELECT DISTINCT a.city, b.city
FROM Customers a, Salespeople b
WHERE a.snum = b.snum;
Это представление показывает все совпадения заказчиков с их продавцами так, что имеется по крайней мере один заказчик в городе_заказчика обслуживаемый продавцом в городе_продавца.
Например, одна строка этой таблицы - London London - показывает, что имеется по крайней мере один заказчик в Лондоне, обслуживаемый продавцом в Лондоне.
Эта строка может быть произведена при совпадении Hoffmanа с его продавцом Peel, причем если оба они из Лондона.
=============== SQL Execution Log ==============
| |
| SELECT * |
| FROM Citymatch; |
| =============================================== |
| custcity salescity |
| --------- --------- |
| Berlin San Jose |
| London London |
| Rome London |
| Rome New York |
| San Jose Barselona |
| San Jose San Jose |
| |
================================================
Рисунок 21.1: Представление совпадения по городам
Однако, то же самое значение будет произведено при совпадении Clemens из Лондона, с его продавцом, который также оказался с именем - Peel. Пока отличающиеся комбинации городов выбирались конкретно, только одна строка из этих значений была произведена.
Даже если вы не получите выбора используя отличия, вы все еще будете в том же самом положении, потому что вы будете тогда иметь две строки в представлении с идентичными значениями, то есть с обоими столбцами равными " Lоndon London ". Эти две строки представления будут отличаться друг от друга, так что вы пока не сможете сообщить, какая строка представления исходила из каких значений базовых таблиц(имейте в виду, что запросы не использующие предложение ORDER BY, производят вывод в произвольном порядке. Это относится также и к запросам используемым внутри представлений, которые не могут использовать ORDER BY. Таким образом, порядок из двух строк не может быть использован для их отличий. Это означает, что мы будем снова обращаться к выводу строк которые не могут быть точно связаны с указанными строками запрашиваемой таблицы.
Что если вы пробуете удалить строку ” London London ” из представления?
Означало бы это удаление Hoffmanа из таблицы Заказчиков, удаление Clemens из той же таблицы, или удаление их обоих? Должен ли SQL также удалить Peel из таблицы Продавцов? На эти вопросы невозможно ответить точно, поэтому удаления не разрешены в представлениях такого типа.
Представление Citymatch - это пример представления только_чтение, оно может быть только запрошено, но не изменено.
ОПРЕДЕЛЕНИЕ МОДИФИЦИРУЕМОСТИ ПРЕДСТАВЛЕНИЯ