Программирование >>  Проектирование интерфейса пользователя 

1 ... 83 84 85 [ 86 ] 87 88 89 ... 153


SELECT * FROM Music

ORDER BY Artist DESC, Title ASC

По умолчанию, т.е. в случае отсутствия одного из компонентов (ASC или DESC), предлагается порядок сортировки по возрастанию.

Группировка столбцов

Предложение GROUP BY применяется для группировки данных в столбцах. К нему

необходимо обращаться при использовании так называемых агрегирующих функций языка SQL, например

Предложение GROUP BY, подобно ORDER BY, в своей общей форме требует задания

списка наименований полей, разделенных запятыми.

Группируя данные по определенным столбцам возвращаемого набора, следует включить в группу либо все столбцы набора данных, либо те из них, которые не использованы в качестве аргументов агрегирующих функций.

Предложение GROUP BY применяется в тех случаях, когда необходимо получить только одну строку из группы строк, в определенных столбцах которых хранятся идентичные значения. Например, таблица TRACKS содержит внешний ключ MUSIC ID, ссылающийся на первичный ключ ID таблицы MUSIC. Выполнив запрос

SELECT C ID FROM TRACKS,

мы получим столько значений, сколько композиций описано в таблице TRACKS, причем числа будут повторяться. Чтобы избежать повторений одинаковых величин (т.е. единожды сослаться на каждый музыкальный альбом), необходимо использовать команду

SELECT Music ld FROM Tracks GROUP BY Music ld

В результате мы получим набор уникальных значений. Представим следующий запрос - он вычисляет количество композиций каждого музыкального альбома (теперь без GROUP BY просто не обойтись):

SELECT Music Id, COUNT ( Music Id ) FROM Tracks GROUP BY MusicId

Указанная команда возвратит набор записей, перечисляющих уникальные коды музыкальных альбомов наряду с числом композиций в каждом из них. Функция COUNT вычисляет количество записей с одинаковыми значениями C ID, а предложение GROUP c ld гарантирует, что будет возвращена только одна запись

для каждой группы совпадающих значений MUSIC ID.

Использование предложения HAVING

SQL не разрешает ссылаться на агрегирующие функции в контексте предложения WHERE. Но иногда необходимо гарантировать соответствие возвращаемого набора даннгх определенным условиям. Предложение HAVING подобно WHERE, в частности, оно помогает ограничить объем множества данных, получаемых в результате выполнения SELECT.

HAVING позволяет включать любое число предикатов, объединенных посредством булевых логических операторов.

Листинг 16.3. демонстрирует пример использования предложения HAVING и оправданного применения вложенного запроса.

Листинг 16.3. Пример использования предложения HAVING и вложенного запроса

1: SELECT * FROM Music WHERE Id =

2: (SELECT Music Id FROM Tracks



3.:: GROUP BY Music Id

.4j; HAVING CDATE (SUM (Track Length) ) > CDATE ( 0 : 6: 0 )

Строка 1 содержит заголовок внешнего запроса, а текст подчиненного запро-I са расположен в строкам Подзапрос группирует записи таблицы TRACKS в соответствии со значениями поля C ID. Предложение HAVING в строке 4 осуществляет сравнение суммы продолжительности звучания всех композиций каждого альбома с константой, равной шести минутам.

В результате выполнения всего запроса будет возвращен набор записей таблицы MUSIC, для каждой из которых существует внешний ключ из таблицы TRACKS и удовлетворяется условие подчиненного запроса. Строка 4 демонстрирует пример употребления встроенной SQL-функции CDATE, выполняющей преобразование числа или строки в значение типа DATETIME. В нашем случае с помощью функции CDATE осуществляется сопоставление суммы временных интервалов (длительностей), выраженных в секундах, с

литеральной константой, равной шести минутам. Примеры использования некоторых встроенных функций SQL рассмотрены ниже, в одноименном разделе этой главы.

Объединение таблиц

Одна из основных целей, которая была поставлена и достигнута разработчиками модели реляционной базы данных, связана с необходимостью исключения неоправданных

потерь пространства для хранения данных. В прежние времена программисты, которые

создавали базы данных, должны были заранее фиксировать число полей таблицы, тре-

буемгх для хранения элементов информации определеннгх типов - скажем, телефонных номеров. В связи с этим проблем возникало немало: программист предусмотрел, например, два таких поля, а в некоторых случаях следовало бы иметь три.

Что делал несчастный с подобной плоской базой данных, в которой все данные

о некотором объекте должны были содержаться в пределах единой монолитной записи? Да, он вынужден б1л изменять структуру таблицы, добавляя в нее недостающие поля. Через какое-то время все мучения повторялись. А что происходило с теми записями, в которых по-прежнему хранились два телефонных номера, а не три или четыре? Добавленные поля оставались пустыми, невостребованными, т.е. место в таблице

(и на диске) безвозвратно терялось.

Те, кто старался предвидеть ход событий, сознательно проектировали таблицы, содержащие множество дыр . Приверженцы другой крайности, пытавщиеся учесть каждый лишний байт, вынуждены были постоянно упражняться с процедурами реструктуризации базы данных и все время исправлять тексты прикладных программ.

Мрачная картина, не правда ли? Но тут на помощь прищди реляционные базы данных (от англоязычного термина Relational Databases - RDBMS. - Прим. перев.). Реляционная модель позволяет распределять порции информации, имеющей отношение к определенному объекту, по нескольким таблицам вместо одной, монолитной и нерасчленимой. Каждая таблица предназначена для хранения определенного подмножества данных.

Например, база данных о покупателях может состоять, скажем, из двух таблиц, одна из которых содержит некоторые статические поля (имя, почтовый адрес и пр.), а

другая предназначена для хранения переменного числа записей, относящихся к каждому покупателю (например, информации о номерах кредитных карточек). Теперь набор кредитных карточек каждого покупателя будет описываться именно таким количеством записей таблицы, какое нужно, - не больше и не меньше.

Реляционные базы данных предполагают наличие механизма объединения хранящейся в нескольких таблицах информации об объекте в целостную картинку . Прежде для решения подобной задачи достаточно было переместиться к конкретной записи единственной таблицы, - конечно, такой способ намного проще, но он сопряжен с потерями, о которых мы говорили выше.



Число таких таблиц реляционной базы данных, которые содержат однородные порции определенной информации (имеющей отношение к объектам одного типа), не ограничено - их может быть две, три и более. Объединение выполняется с помощью дополнительных ключевых столбцов и, безусловно, более трудоемко в практической реализации по сравнению с методами обработки плоских таблиц - но выигрыш, тем не менее, очевиден.

Процесс и результат сбора таких данных об определенном объекте, которые хранятся в нескольких таблицах, принято называть объединением таблиц. В разделе Предложение WHERE и вложенные команды SELECT речь шла об одном из вариантов этого механизма - так называемом неявном объединении, когда несколько однородных полей данных из нескольких таблиц сопоставляются в контексте предложения WHERE. В этом

случае возвращаемый набор данных будет содержать все записи с найденными соответствиями. Разумеется, это полезно. Однако ситуация может усложниться, как в примере, рассмотренном выше (в нем речь шла о таблицах, содержащих сведения о покупателях и

их кредитных карточках), в случае, если у каких-либо покупателей просто нет кредитных карт. Просмотрите такой гипотетический запрос:

SELECT FROM Custoraer, Credit Cards

WHERE Justomer.Id = Credit Cards.Customer ld

(Выражение Customer. Id означает ссылку на поле ID таблицы CUSTOMER. Это

пример использования общеупотребительного - полного - синтаксиса обращения к

полю таблицы.) Как известно, credit cards . customer id - внешний ключ, ссылающийся на поле CUSTOMER. ID. Если таблица credit cards не содержит сведений о кредитных карточках какого-либо покупателя, предложение WHERE не сработает и в возвращенном наборе данных этот покупатель вообще не будет упомянут. Теперь представьте последствия подобного поведения программы, обрабатывающей счета за

услуги, которые фирма предоставила потребителям: незамеченные счастливчики

торжествуют, вы, автор шедевра, уволены, у шефа инфаркт, компания - на грани банкротства. ( А в остальном ... все хорошо! )

Это как раз тот случай, когда вас выручит выражение на основе служебного слова JOIN. Оператор JOIN работает с двумя аргументами-таблицами: первую называют левой, а вторую - правой. Существует три разновидности конструкций JOIN - INNER JOIN, LEFT JOIN и RIGHT JOIN. Каждая из них служит определенной цели, и о них

будет рассказано более подробно. Оператор INNER JOIN

Конструкция INNER JOIN равнозначна условию эквивалентности, используемому в предложении WHERE. Оператор INNER JOIN позволяет возвратить все записи, для которых выполняется условие равенства содержимого столбцов двух объединяемых таблиц. Приведем соответствующий пример:

SELECT *

FROM Music INNER lOIN Trades ON Music. Id = Tracks. Music Id

Данная команда возвратит все записи таблиц MUSIC и TRACKS, для котор1х MUSIC. ID = tracks .music. ID. Она равносильна следующему выражению:

SELECT * FROM Music, Tracks

WHERE Music.Id = Tracks.Music Id

Оператор FT JOIN

Оператор LEFT JOIN применяется в тех случаях, когда следует вернуть все записи левой таблицы и только те строки правой, значения полей которых соответствуют данным левой таблицы. Поэтому в полях правой таблицы возвращенного множества данных допускаются значения null. Рассмотрим пример:



1 ... 83 84 85 [ 86 ] 87 88 89 ... 153

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика