Упорядочивание записей
Оператор ORDER BY используется для упорядочивания записей результирующего набора данных. Записи сортируются в соответствии с порядком следования полей и их значений. Если сортировка будет производиться по возрастанию, то следует использовать параметр ASC. Для сортировки по убыванию используется параметр DESC.
Оператор
Select Dep, Fam, Year_r From Pers Order By Year_r
задает упорядочивание возвращаемых значений по нарастанию года рождения, а оператор
Select Dep, Fam, Year_r From Pers Order By Year_r Desc
располагает результаты по убыванию значений.
В качестве примера можно привести несложный SQL-запрос:
SELECT CompanyName, ContactName, City FROM Customers
ORDER BY City
Если в списке после ORDER BY перечисляется несколько полей, то первое из них главное и сортировка проводится, прежде всего, по значениям этого поля. Записи, имеющие одинаковое значение первого поля упорядочиваются по значению второго поля. Например, оператор
Select Dep, Fam, Year_r FROM Pers ORDER By Dep, Fam
сортирует записи прежде всего по отделам, а внутри каждого отдела – по алфавиту. Оператор
Select Dep, Fam, Year_r, Sex FROM Pers ORDER By Dep, Sex, Fam
сортирует записи по отделам, полу и алфавиту.
К созданному выше запросу можно добавить сортировку по количеству городов в порядке убывания записей:
SELECT City, COUNT (*) AS Количество, MAX (PostalCode) AS Почтовый_индекс FROM Customers Where City <> 'Buenos Aires'
GROUP BY City HAVING COUNT (*) >=3
ORDER BY Количество DESC, City ASC
Нужно обратить внимание на то, что в качестве аргумента параметра ORDER BY было использовано название поля, так как его значения являются результатом агрегатной функции COUNT. Для включения сортировки по убыванию был указан параметр DESC, расположенный после названия поля.
6.2 Многотабличные запросы
Как правило, при проектировании таблиц в них стараются включать только те поля, которые однозначно связаны с данной сущностью. Это делается для того, чтобы было проще модифицировать базу данных и поддерживать ее целостность. В связи с этим возникает необходимость создания многотабличных запросов, то есть запросов, использующих для формирования результата данные из нескольких таблиц.
Объединение таблиц
Во многих случаях требуется получать данные из нескольких таблиц и сводить их в одну результирующую таблицу. Такая операция называется объединением таблиц. При объединении производится связывание полей разных таблиц. При этом между полями устанавливаются связи за счет использования соответствующих справочных значений. После оператора FROM таблицы перечисляются через запятую. Полное имя поля фактически состоит из имени таблицы и самого поля, разделенного точкой. Если все столбцы объединяемых таблиц имеют разные имена, то к ним можно обращаться напрямую, не указывая имя таблицы, которой они принадлежат.
Пусть, например, мы хотим получить список сотрудников всех производственных подразделений. В таблице Pers мы имеем список сотрудников с указанием в поле Dep подразделений, в которых они работают. А в таблице Dep мы имеем список всех подразделений в поле Dep и характеристику каждого подразделения в поле Proisv (true, если подразделение производственное). Тогда получить список сотрудников всех производственных подразделений можно оператором:
Select Pers.* From Pers, Dep
WHERE (Pers.Dep=Dep.Dep) AND (Dep.Proisv=true)
Перед полем Proisv ссылку на таблицу можно опустить, так как оно используется только в одной таблице. В операторах, работающих с несколькими таблицами, обычно каждой таблице дается псевдоним, сокращающий ссылки на таблицы, а иногда придающий им некоторый смысл. Псевдоним таблицы может записываться в списке таблиц после слова FROM, отделяясь от имени таблицы пробелом. Приведенный выше оператор может быть переписан следующим образом:
Select P.* From Pers P, Dep D
WHERE (P.Dep=D.Dep) AND (D.Proisv=true)
В этом примере таблице Pers дан псевдоним P, а таблице Dep – D.
Возможно самообъединение таблицы. В этом случае одной таблице даются два псевдонима. Пусть, например, мы хотим найти всех ровесников в организации. Это можно сделать оператором:
Select p1.fam, p2.fam, p1.Year_r, From Pers p1, Pers p2
Where (p1.Year_r=p2.Year_r) AND (p1.Fam!=p2.Fam)
В этом примере для таблицы Pers введено два псевдонима p1, p2. В конструкции Where мы ищем в этих якобы разных таблицах записи с одинаковым годом рождения.
Второе условие p1.fam!=p2.fam нужно, чтобы сотрудник не отображался как ровесник сам себя. Правда, приведенный оператор выдает в результате по две записи на каждую пару ровесников, сначала, например, «Николаев – Иванов», а потом «Иванов – Николаев». Чтобы исключить такое дублирование можно добавить еще одно условие:
Select p1.fam, p2.fam, p1.Year_r, From Pers p1, Pers p2
Where (p1.Year_r=p2.Year_r) AND (p1.Fam!=p2.Fam) AND (p1.Fam
Дополнительное условие упорядочивает появление фамилий в p1 и p2 и исключает дублирование результатов.
Для рассмотрения принципов работы многотабличных запросов рассмотрим еще один пример. Предположим, необходимо узнать названия судов с грузом, которые отправила каждая компания, вес отправленного груза, дату его отправки, контактное лицо и его телефон:
SELECT Orders.ShipName AS Судно, Orders.Freight AS Вес_груза, Orders.OrderDate AS Дата_Отправки, Customers.ContactName, Customers.Phone FROM Customers, Orders WHERE Customers.CustomerlD = Orders.CustomerlD
При выполнении запроса были выбраны поля только тех записей, у которых значения поля CustomerID совпадали. При помощи этого поля были объединены и связаны две таблицы.
Этот запрос можно усложнить. Предположим, что необходимо получить информацию именно о тех судах, груз которых весил более 500 тонн и был отправлен в период с 11.03.2016 по 11.07.2016:
SELECT Orders.ShipName AS Судно, Orders.Freight AS Вес_груза, Orders.OrderDate AS Дата_Отправки, Customers.ContactName, Customers.Phone FROM Customers, Orders WHERE Customers.CustomerlD = Orders.CustomerlD AND Freight > 500 AND Orders.OrderDate BETWEEN '03.11.2016' AND '07.12.2016'
При помощи этого механизма можно объединять более двух таблиц, указывая связующие поля и условия отбора записей.
6.3 Вложенные подзапросы
Результаты, возвращаемые оператором Select, можно использовать в другом операторе Select. Причем это относится и к операторам, возвращающим совокупные характеристики, и к операторам, возвращающим множество значений. Например, найдем фамилию самого молодого сотрудника.
Select Fam, Year_r From Pers
Where Year_r=(Select max(Year_r) From Pers)
В этом операторе второй вложенный оператор Select max(Year_r) From Pers возвращает максимальный год рождения, который используется в элементе Where основного оператора Select для поиска сотрудника или сотрудников, чей год рождения совпадает с максимальным. Найдем всех однофамильцев двух организаций с помощью вложенного запроса.
Select * From Pers Where Fam IN (Select Fam From Pers1)
Вложенный оператор Select Fam From Pers1 возвращает множество фамилий из таблицы Pers1, а конструкция Where основного оператора Select отбирает из фамилий в таблице Pers те, которые имеются во множестве фамилий из Pers1.
Вложенные запросы могут использоваться в качестве дополнительных условий отбора записей. Для того чтобы понять механизм работы этого условия, следует рассмотреть простой запрос, в котором выводится список названий судов, которые обслужил сотрудник по имени Steven Buchanan и даты их отправки:
SELECT ShipName AS Название_судна, OrderDate AS Дата_отправки FROM Orders WHERE EmployeelD IN (SELECT EmployeelD FROM Employees
WHERE FirstName = 'Steven' AND LastName = 'Buchanan')
В этом запросе оператор IN может быть заменен оператором равенства. Однако следует учитывать, что оператор IN возвращает массив значений, а скалярный оператор равенства — только одно.
Выполнение запросов с вложенными подзапросами всегда начинается с подзапроса, располагающегося на самом нижнем уровне. В рассматриваемом подзапросе отыскивается индивидуальный номер сотрудника EmployeelD по его имени и фамилии. Основной запрос принимает найденное значение в качестве параметра.
Можно усложнить вложенный запрос. В примере будет приведен запрос, отображающий список сотрудников, обслуживших более девяноста судов:
SELECT TitleOfCourtesy, FirstName, LastName FROM Employees
WHERE EmployeeID IN (SELECT EmployeeID FROM Orders GROUP BY EmployeeID HAVING COUNT(EmployeeID) > 100) ORDER BY FirstName, LastName
Во вложенном запросе производится отбор идентификаторов работников, встречающихся в таблице более 100 раз.
Достарыңызбен бөлісу: |