|
Программирование >> Проектирование интерфейса пользователя
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. Рассмотрим пример:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |