Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

699

.pdf
Скачиваний:
4
Добавлен:
15.11.2022
Размер:
3.63 Mб
Скачать

,hD,slr,title, count(c.Memberof) as Member-ship,count(c.manages) as projects FROM Manager c

--SELECT fnm,lnm,BDt,cmt,age,gnd,adrs,eml,ppth,clgr

,hD,slr,title,count(c.spouse)

as

Spouse,count(c.children)

 

as

Children,count(c.Memberof)

as

as

Membership,count(edocs)

Docu-

ments,count(c.manages)

 

as

Projects,count(team) as

Team,count(cabs)

as Cabinets,count(priemm)

as

Receptions

FROM Manager c

 

 

--SELECT

 

 

fnm,lnm,BDt,cmt,age,gnd,adrs,eml,ppth,clgr

,hD,slr,title,count(c.spouse)

as

Spouse,count(c.children)

 

as

Children,count(c.Memberof)

as

as

Membership,count(edocs)

Docu-

ments,count(c.manages)

 

as

Projects,count(team) as

Team,count(cabs)

as

Cabinets,count(Direct)

as

DirectMovie,count(priemm)

as

Receptions

FROM MovieDirector c

 

 

 

--SELECT

 

 

fnm,lnm,BDt,cmt,age,gnd,adrs,eml,ppth,clgr

,hD,slr,title,count(c.spouse)

 

as

Spouse,count(c.children)

 

as

Children,count(c.Memberof)

as

as

Membership,count(edocs)

Docu-

ments,count(c.manages)

 

as

Projects,count(team) as Team,count(cabs)

as Cabinets,count(priemm)as

 

Receptions,

count(patients) as Patients FROM Doctor c --SELECT

fnm,lnm,BDt,cmt,age,gnd,adrs,eml,ppth,clgr

,hD,slr,count(c.spouse)

as

171

 

Spouse,count(c.children) as Children,count(c.Memberof) as Membership,count(c.WorksIn) as Projects,count(c.reportsto) as Reportsto,count(priemp)as Receptions,count(edocs) as Documents, count(assistantof) as Assistantof FROM Employee c

--SELECT fnm,lnm,BDt,cmt,age,gnd,adrs,eml,ppth,clgr ,hD,slr,count(c.spouse) as Spouse,count(c.children) as Children,count(c.Memberof) as Membership,count(c.WorksIn) as Projects,count(c.reportsto) as Reportsto,count(priemp)as Receptions,count(edocs) as Documents,count(c.Biography) as Biography, count(assistantof) as Assistantof FROM Artist c

SELECT fnm,lnm,BDt,cmt,age,gnd,adrs,eml,ppth,clgr ,hD,slr,count(c.spouse) as Spouse,count(c.children) as Children,count(c.Memberof) as Membership,count(c.WorksIn) as Projects,count(c.reportsto) as Reportsto,count(priemp)as Receptions,count(edocs) as Documents,count(c.Doctors) as Doctors, count(assistantof) as Assistantof FROM Patient c

2.21. Вложенные запросы

Предикат с квантором имеет следующий синтаксис:

<quantified predicate>::= <value expression>

172

<comp op> <quantifier> <subquery> <quantifier>::=

<all> | <some> <all>::= ALL <some>::= SOME | ANY

Обозначим через x результат вычисления арифметического выражения левой части предиката, а через S – результат вычисления подзапроса.

Предикат "x <comp op> ALL S" имеет значение true, если S пусто или значение предиката "x <comp op> s" равно true для каждого s, входящего в S. Предикат "x <comp op> ALL S" имеет значение false, если значение предиката "x <comp op> s" равно false хотя бы для одного s, входящего в S. В остальных случаях значение предиката "x <comp op> ALL S" равно unknown.

Предикат "x <comp op> SOME S" имеет значение false,

если S пусто или значение предиката "x <comp op> s" равно false для каждого s, входящего в S. Предикат "x <comp op> SOMES" имеет значение true, если значение предиката "x <comp op>s" равно true хотя бы для одного s, входящего в S. В остальных случаях значение предиката "x <comp op> SOME S" равно unknown.

Мы можем использовать любые операторы, используемые с ключевым словом WHERE (рассмотрены в под-

разд. 2.19).

Водном запросе может быть несколько подзапросов, синтаксис у такого запроса следующий: SELECT имя_столбца FROM имя_таблицы WHERE часть условия

IN (SELECT имя_столбца FROM имя_таблицы WHERE

часть условия IN (SELECT имя_столбца FROM имя_таблицы WHERE условие));

Впримере указано два запроса, которые выдают один

итот же результат:

173

SELECT name FROM users WHERE id_user IN (SELECT id_author FROM topics WHERE top-ic_name='велосипеды');

SELECT name FROM users WHERE id_user = (SELECT id_author FROM topics WHERE topic_name='велосипеды');.

Предикат exists

Предикат exists имеет следующий синтаксис:

< exists predicate>::= EXISTS <subquery>

Значением этого предиката всегда является true или false, и это значение равно true тогда и только тогда, когда результат вычисления подзапроса не пуст.

Выдать названия поставщиков, поставляющих продукт

с номером 11.

 

Название

SELECT

FROM

Поставщики

 

 

WHERE EXISTS

 

*

 

(

SELECT

 

 

FROM

Поставки

 

 

WHERE ПС = Поставщики.ПС

Система

 

AND

ПР = 11 );

последовательно

выбирает строки таблицы

«Поставщики», выделяет из них значения столбцов «Название» и ПС, а затем проверяет, является ли истинным условие существования, т.е. существует ли в таблице «Поставки» хотя бы одна строка со значением ПР = 11 и значением ПС, рав-ным значению ПС, выбранному из таблицы «Поставщики». Если условие выполняется, то полученное значение столбца «Название» включается в результат.

Выдать название и статус поставщиков, не поставляющих продукт с номером 11 [19]:

SELECT Название, Статус FROM Поставщики

174

WHERE NOT EXISTS

*

(

SELECT

 

FROM

Поставки

 

WHERE ПС = Поставщики.ПС

 

AND

ПР = 11 );

Раздел GROUP BY и раздел HAVING

Если в табличном выражении присутствует раздел GROUP BY, то далее выполняется он. Синтаксис раздела GROUP BY следующий:

< group by clause>::=GROUP BY <column specification>[{, <column specification>}...]

Синтаксис раздела HAVING следующий:

<having clause>::=HAVING <search condition>

Результатом выполнения раздела HAVING с GROUP BY является сгруппированная таблица, содержащая только те группы строк, для которых результат вычисления условия поиска есть true. Можно применять агрегатные функ-

ции COUNT, SUM, AVG, MIN и MAX.

Следующий запрос вернет список отделов, в которых работает более одного сотрудника [20]:

SELECT DepartmentName, COUNT(*) FROM employee,department

WHERE employee.DepartmentID = department.DepartmentID

GROUP BY DepartmentName HAVING COUNT(*)>1;

Агрегатные функции и результаты запросов

в стандарте SQL/89 определены пять стандартных агрегатных функций: COUNT – число строк или значений, MAX – максимальное значение, MIN – минимальное значение, SUM – суммарное значение и AVG – среднее значение.

175

Вычисление функции COUNT(*) производится путем подсчета числа строк в заданном множестве. Все строки считаются различными, даже если они состоят из одного столбца со значением null во всех строках.

Если агрегатная функция специфицирована с ключевым словом DISTINCT, то список значений строится из значений указанного столбца. В нем устраняются значениядубликаты [33].

2.22.Запрос с выборкой из нескольких таблиц

Впримере таблицы связываются по полям (внешним и первичным ключам). Ищутся значения «Код группы» и внешний ключ на группу из таблицы «Расписание» и т.д.

Врезультате выдаются только те записи, которые полностью совпадают, т.е. строки, где отсутствует поле (ключ), отбрасываются.

Пример T-Sql

/*Расписание лекций*/

select s.fam 'Фамилия преподавателя', p.pred 'Предмет', e.d1 ' Дата лекции',e.t1 'Время ', g.cgr 'Группа', g.course 'Курс', g.cur 'Куратор'

from Gro g,pred p, rasp e,prep s

where e.cgr=g.cgr and e.Cprep=s.Cprep and e.cpr=p.cpr

order by s.fam

Запрос Кафедра + преподаватель + должность:

select k.kaf 'Кафедра',d.dolj'Должность',s.fam 'Фамилия преподават.'

from prep s,dolj d,kafed k,kaf_prep kp where s.Cprep=kp.Cprep and kp.Ckaf=k.Ckaf and kp.Cdolj=d.Cdl

order by k.kaf, s.fam

176

Пример Oracle

Создайте запрос, который бы возвращал информацию из таблиц employees и jobs схемы hr:

SELECT first_name AS "Имя", last_name As "Фамилия", Job_Title As "Должность", (max_salary - salary) AS "Разница с макси-

мальной"

FROM hr.employees, hr.jobs WHERE (hr.employees.job_id = hr.jobs.JOB_ID) ORDER BY "Разница с максимальной" DESC Результат:

Steven King President 16000

Lex De Haan Administration Vice President 13000 [17]

Объединение нескольких таблиц. Оператор JOIN

Чтобы получить строки из нескольких таблиц, можно использовать оператор JOIN. JOIN – оператор языка SQL, который является реализацией операции соединения реляционной алгебры. Входит в раздел FROM операторов SELECT, UPDATE или DELETE. В большинстве СУБД при указании слов LEFT, RIGHT, FULL слово OUTER можно опустить. Слово INNER также в большинстве СУБД можно опустить. В общем случае СУБД при выполнении соединения проверяет условие (предикат) condition. Для CROSS JOIN условие не указывается [20].

Внутреннее объединение таблиц. Оператор INNER JOIN

Объединения, которые связывают строки одной таблицы со строками другой таблицы (а может, еще и третьей таблицы), называются внутренними объединениями [20].

SELECT * FROM

Person

177

INNER JOIN

City

ON Person.CityId = City.Id

Результат:

 

 

 

Person.Name

Person.CityId

City.Id

City.Name

Андрей

1

1

Москва

Леонид

2

2

Санкт-

 

 

 

Петербург

Сергей

1

1

Москва

Пример для T-SQL

/*Общее кол-во часов для преподавате-

лей s.fam='Ухов'*/

 

 

SELECT Cpr,d1,t1,clock,fam

AS

e

FROM prep AS s INNER JOIN Rasp

ON s.Cprep=e.Cprep where s.fam='Ухов'

 

 

SELECT SUM(e.clock) AS 'Общее кол-во'

FROM prep AS s INNER JOIN Rasp

AS

e

ON s.Cprep=e.Cprep where s.fam='Ухов'

 

 

Результат запроса «Общее количество часов для преподавателя 24»:

/*Студенты: факультет, группа, форма

обучения, направление */

f.fac

AS

SELECT

f.Cfc

+

' ' +

'Факультет', g.Cgr AS

'Группа',

g.Course

AS 'Курс',

g.Cur

AS

'Куратор',

s.FIO

AS

'Студент', s.fact_adr AS 'Фактич. адрес', s.Nstudbil AS 'Студ. билет', s.adr AS 'Адрес', s.tel AS 'Телефон', Fob.fob, napr.napr, f.fac

FROM fac AS f INNER JOIN

Gro AS g ON f.Cfc = g.Cfc INNER JOIN stud AS s ON g.Cgr = s.Cgr INNER

JOIN

Fob ON g.Cu = Fob.Cu INNER JOIN napr ON g.Cna = napr.Cna

178

Внешнее объединение таблиц. Оператор OUTER JOIN

Возможно полное внешнее объединение, которое извлечет все строки из обеих таблиц и свяжет между собой те, которые могут быть связаны. Ключевое слово для полного внешнего объединения – FULL OUTER JOIN.

SELECT * FROM

Person

FULL OUTER JOIN City

ON Person.CityId = City.Id

Результат:

Person.Name

Person.CityId

City.Id

City.Name

Андрей

1

1

Москва

Сергей

1

1

Москва

Леонид

2

2

Санкт-

 

 

 

Петербург

NULL

NULL

3

Казань

Григорий

4

NULL

NULL

LEFT OUTER JOIN

Оператор левого внешнего соединения LEFT OUTER JOIN соединяет две таблицы. Ключевое слово – LEFT OUTER JOIN, указывает, что из таблицы слева надо взять все строки.

SELECT * FROM

Person

LEFT OUTER JOIN City

ON Person.CityId = City.Id

Результат:

Person.Name

Person.CityId

City.Id

City.Name

Андрей

1

1

Москва

Леонид

2

2

Санкт-

 

179

 

 

 

 

1

Петербург

Сергей

1

Москва

Григорий

4

NULL

NULL

Запрос для получения всех пользователей и тем, ими созданных. Если пользователь не создавал тему, но в соответствующем столбце стоит значение NULL:

SELECT users.name, topics.topic_name FROM users LEFT OUTER JOIN topics ON

users.id_user=topics.id_author;

RIGHT OUTER JOIN

Оператор правого внешнего соединения RIGHT OUTER JOIN соединяет две таблицы. В запросе будут выбираться все строки из правой таблицы и имеющиеся, связанные с ними из левой таблицы [11, 20].

SELECT * FROM

Person

RIGHT OUTER JOIN City

ON Person.CityId = City.Id

Результат:

Person.Name

Person.CityId

City.Id

City.Name

Андрей

1

1

Москва

Сергей

1

1

Москва

Леонид

2

2

Санкт-

 

 

 

Петербург

NULL

NULL

3

Казань

CROSS JOIN

Оператор перекрестного соединения, или декартова произведения, CROSS JOIN соединяет две таблицы.

Заголовок таблицы-результата является объединением (конкатенацией) заголовков соединяемых таблиц.

Тело результата логически формируется следующим образом. Каждая строка одной таблицы соединяется с каж-

180

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]