Выборка данных из базы данных с использованием языка SQL Цель работы: изучить принципы работы с базой данных в архитектуре клиент-сервер, изучить спецификации запроса языка баз данных SQL, получить практические навыки составления и содержательной интерпретации запросов выборки данных (операторов SELECT), а также их выполнения на SQL-сервере с использованием клиентских утилит. Порядок выполнения работы 1. Изучить структуру и элементы SQL-запроса выборки, в том числе разделы FROM, WHERE, GROUP BY, HAVING, ORDER BY, а также предикаты условия поиска и агрегатные функции. 2. Изучить операции реляционной алгебры (соединение, пересечение, объединение, разность и др.). 3. Изучить утилиту Query Analyzer, входящую в набор клиентских утилит для СУБД SQL Server. 4. Изучить состав базы данных книготорговой компании (база данных pubs), структуру и семантику ее таблиц. 5. Получить у преподавателя номер варианта задания. 6. В соответствии с вариантом задания типа А произвести содержательную интерпретацию заданных SQL-запросов, выполнить их на SQL-сервере с использованием клиентских утилит Query Analyzer или SQL Enterprise Manager (SQL-EM), проинтерпретировать результаты выполнения запросов. 7. В соответствии с вариантом задания В составить SQL-запросы по их заданному содержательному описанию, выполнить SQL-запросы на SQL-сервере с использованием клиентских утилит Query Analyzer или SQL Enterprise Manager, проинтерпретировать результаты выполнения запросов. 8. Оформить отчет. Содержание отчета 1) титульный лист; 2) цель работы; 3) тексты SQL-запросов (указанием номера запроса в перечне) , результаты выполнения запросов и их содержательная интерпретация по заданиям типа А; 4) заданное содержательное описание запросов ( с указанием номера описания в перечне описаний), текст SQL-запроса и результаты выполнения запросов по заданиям типа В; 5) вывод. Основные сведения Язык SQL Первый международный стандарт языка SQL был принят в 1989 г. (SQL/89). В конце 1992 г. Был принят новый международный стандарт SQL/92. “Родным” языком Microsoft SQL Server является язык Transact-SQL (T-SQL), являющийся диалектом стандартного языка SQL. T-SQL поддерживает большинство возможностей языков SQL/89 и SQL/92, а также ряд расширений, увеличивающих возможность программирования и гибкость языка. В частности, в язык T-SQL добавлены конструкции для задания последовательности операций управления в программе (например, if и while), локальных переменных и других конструкций, позволяющих писать более сложные запросы и строить программные объекты, хранящиеся на сервере, в том числе процедуры и триггеры. Язык SQL включает следующие языки: язык определения данных (Data Definition Language или DDL), предназначенный для добавления, модификации и удаления данных в таблицах; язык модификации данных (Data Modification Language или DML), предназначенный для добавления, модификации и удаления данных в таблицах. В синтаксических конструкциях при описании языка будут использоваться следующие соглашения. Нетерминальные элементы заключаются в угловые скобки <>. Необязательная конструкция заключается в квадратные скобки []. Запись вида {A}… означает повторение конструкции А произвольное число раз (включая нулевое). Вертикальные разделители | читаются как “ИЛИ” и служат для выбора одной из конструкций, заключенных в скобки. Оператор SELECT Оператор SELECT используется для запросов к базе данных и выборки результатов. Синтаксис оператора SELECT следующий: <оператор SELECT>::= SELECT [ALL | DISTINCT] <список выборки> <табличное выражение> ORDER BY <спецификация сортировки>] <табличное выражение>::= FROM <имя таблицы>[{,<имя таблицы>}…] [WHERE <условие поиска>] [GROUP BY <имя столбца> [{,<имя столбца>}…] [HAVING <условие поиска>] Если задано ключевое слово DISTINCT, то из результирующей таблицы удаляются повторяющиеся строки. Список выборки определяет, какие столбцы должны быть возвращены в результирующую таблицу. Данный список представляет список арифметических выражений над значениями столбцов таблиц из раздела FROM и констант. В простейшем случае он может быть, например, списком имен некоторых столбцов таблиц из раздела FROM. В случае, если вместо списка выборки стоит звездочка (*), то выбираются все столбцы таблиц из раздела FROM. В разделе FROM определяются таблицы, из которых будут извлекаться данные. Следует отметить, что рядом с именем таблицы можно указывать еще одно имя - синоним имени таблицы, который можно использовать в других разделах табличного выражения. Раздел WHERE служит своего рода фильтром при отборе данных. Выполнение раздела GROUP BY оператора выборки сводится к разбиению результирующей таблицы на множество групп строк, которое состоит из минимального числа таких групп, в которых для каждого столбца из списка столбцов раздела GROUP BY во всех строках каждой группы, включающей более одной строки, значения этого столбца совпадают. Результатом выполнения раздела HAVING является сгруппированная таблица, содержащая только те группы строк, для которых результат вычисления условия поиска является истинным. Условие поиска раздела HAVING задает условие на целую группу, а не на индивидуальные строки, поэтому в данном случае прямо можно использовать только столбцы, указанные в качестве столбцов группирования в разделе GROUP BY. Раздел ORDER BY позволяет установить желаемый порядок просмотра результирующей таблицы. Спецификация сортировки имеет следующий синтаксис: <спецификация сортировки>::= {<целое без знака> | <имя столбца>} [ASC | DESC] Как видно, фактически задается список столбцов, и для каждого столбца указывается порядок просмотра строк результирующей таблицы в зависимости от значений этого столбца (ASC - по возрастанию (умолчание), DESC - по убыванию). Указывать сортируемый столбец можно по имени или по порядковому номеру в результирующей таблице. Предикаты условия поиска В условии поиска могут использоваться следующие предикаты: предикат сравнения, предикат BETWEEN , предикат IN, предикат LIKE, предикат NULL, предикат с квантором и предикат EXISTS. Предикат IN определяется следующим образом: <предикат IN>::= <выражение> [NOT] IN (<значение> [,<значение>...] | .<подзапрос>) Значение предиката является истинным, когда значение левого операнда совпадает хотя бы с одним значением списка правого операнда. Использование ключевого слова NOT осуществляет отрицание результата. Подзапрос- это запрос, используемый в предикате условия поиска. Результатом выполнения подзапроса является единственный столбец. Предикат BETWEEN определяется следующим образом: <предикат BETWEEN>::= <выражение> [NOT] BETWEEN <выражение> AND <выражение> По определению результат x BETWEEN y AND z тот же самый, что результат логического выражения x>=y AND x<=z. Предикат LIKE имеет следующий синтаксис: <предикат LIKE>::= <имя столбца> [NOT] LIKE <шаблон>[ESCAPE <escape-символ>] Значение предиката LIKE является истинным, если шаблон является подстрокой заданного столбца. При этом, если раздел ESCAPE отсутствует, то при составлении шаблона со строкой производится специальная интерпретация символов-заместителей шаблона: символ подчеркивания (‘_’) обозначает любой одиночный символ, символ процента (‘%’) обозначает последовательность произвольных символов произвольной длины (может быть нулевой), парные квадратные скобки представляют любой символ, записанный в скобках. Если же раздел ESCAPE присутствует и специфицирует некоторый одиночный символ x, то пары символов ‘x_’ и ‘x%’ представляют одиночные символы ‘_’ и ‘%’ соответственно. Предикат NULL описывается синтаксическим правилом: <предикат NULL>::= <имя столбца> IS [NOT] NULL Значение ‘x IS NULL’ является истинным, когда значение x неопределено. Предикат EXISTS имеет следующий синтаксис: <предикат EXISTS>::= EXISTS <подзапрос> Значение предиката является истинным, когда результат вычисления подзапроса не пуст. Агрегатные функции Агрегатные функции (функции множества) в запросе предназначены для вычисления некоторого значения для заданного множества строк. Таким множеством строк может быть группа строк, если агрегатная функция применяется к сгруппированной таблице, или вся таблица. В языке SQL определены следующие агрегатные функции: AVG - функция определения среднего значения; MAX - функция определения максимального значения; MIN - функция определения минимального значения; SUM - функция суммирования значений; COUNT - функция для подсчета числа строк или значений. Грамматика агрегатных функций следующая: <агрегатная функция>::= COUNT(*) | <distinct-функция> | <all-функция> <distinct-функция>::= {AVG | COUNT | MAX | MIN | SUM} (DISTINCT <имя столбца>) <all-функция>::= {AVG | MAX | MIN | SUM} ([ALL]<выражение>) Вычисление функции COUNT(*) производится путем подсчета числа строк в заданном множестве. Функция типа distinct выполняет вычисления только над одним столбцом, а в вычислениях используются только уникальные значения столбца. При использовании функции типа all список значений формируется из значений арифметического выражения, вычисляемого для каждой строки заданного множества. Операции реляционной алгебры Большинство SQL-запросов требует одновременного обращения к нескольким таблицам. Часто такого рода запросы основываются на операциях реляционной алгебры, в частности, соединения, декартова произведения, объединения, пересечения и разности. При соединении двух таблиц по некоторому условию образуется результирующая таблица, строки которой являются конкатенацией (сцеплением) строк первой и второй таблиц и удовлетворяют этому условию. Операцию соединения можно реализовать с использованием обычного SQL-запроса типа SELECT-FROM-WHERE. По стандарту ANSI операция соединения таблиц может указываться явно в разделе FROM. Синтаксис раздела FROM в этом случае следующий: <раздел FROM>::= FROM <имя таблицы> [JOIN <имя таблицы> ON <условие соединения> ...] При выполнении декартова произведения двух таблиц производится таблица, строки которой являются конкатенацией строк первой и второй таблиц. Операцию декартова произведения можно реализовать с использованием SQL-запроса типа SELECT-FROM. По стандарту ANSI операция декартова произведения может указываться явно в разделе FROM с использованием ключевой фразы CROSS JOIN. При выполнении операции объединения двух таблиц производится таблица, включающая все строки, входящие хотя бы в одну из таблиц-операндов. При этом число столбцов и типы данных этих столбцов должны быть одинаковыми для всех операндов. Для объединения результирующих таблиц операторов SELECT используется ключевое слово UNION. Операция пересечения двух таблиц производит таблицу, включающую все строки, входящие в обе исходные таблицы. Таблица, являющаяся разностью двух таблиц, включает все строки, входящие в таблицу первый операнд, такие, что ни одна из них не входит в таблицу, являющуюся вторым операндом. Работа с утилитой Query Analyzer Клиентская утилита Query Analyzer используется для тестирования SQL-запросов. После запуска данной утилиты необходимо подключиться к серверу. При этом в диалоговом окне подсоединения (connect dialog box) необходимо указать имя сервера, идентификатор пользователя и пароль. После регистрации окно Query Analyzer отображает в заголовке информацию о сервере, пользователе и текущей базе данных. Окно запросов при этом открыто. Пункты меню File управляют сохранением, чтением и печатью запросов, а также подключениями к серверам. Меню Edit позволяет копировать и искать строки. Меню Query управляет выполнением запросов и предлагает доступ к некоторым общим установкам подключения. Пункты меню Help и Window работают практически так же, как и в любом приложении Windows. Кнопки панели инструментов (toolbar) дают те же возможности, что и пункты меню, но при однократном нажатии отдельные кнопки особенно удобны. Первая кнопка слева (кнопка Новый запрос) позволяет создать новое окно запросов и новое подключение к данному серверу с использованием того же идентификатора пользователя и пароля. Кроме того, оно позволяет автоматически использовать ту же базу данных, что и текущее подсоединение. Одновременные подсоединения удобны, поскольку они позволяют работать как два отдельных пользователя, тестируя блокировку и многопользовательское поведение, или дают возможность быстро посмотреть значение, необходимое для написания сложного запроса в другом окне. Другие полезные кнопки находятся справа от окна запросов. Крайняя левая кнопка из трех (перечеркнутая крестиком пиктограмма запроса) закрывает текущий запрос и подсоединение. Именно таким образом отменяется действие кнопки “Новый запрос”. Вторая кнопка с указывающей направо стрелкой становится зеленой, когда вводится любой текст в текстовой области окна запросов. Эта кнопка выполнения. При нажатии ее по окончании ввода запроса, текст запроса будет передан на сервер. Кнопка будет серой, когда в окне нет или когда запрос уже выполняется. Третья кнопка - это квадрат, имеющий красный цвет, когда запрос выполняется. Это кнопка отмены запроса. Текстовая область может использоваться для ввода запроса, просмотра результата выполнения запроса, просмотра статистики ввода-вывода при выполнении запроса, а также для просмотра плана запроса (?). Для перехода к указанным режимам использования текстовой области необходимо выбрать закладки Query, Results, Statistics I/O и Showplan, соответственно. Вызвать утилиту Query Analyzer можно запустив загрузочный модуль isqlw.exe. Необходимыми динамическими библиотеками при работе утилиты являются: ntdblib.dll, sqlgui32.dll, sqlsvc32.dll и sqlqry32.dll. Кроме того, вызвать утилиту Query Analyzer можно работая с интегрированной утилитой SQL Enterprise Manager. Для этого необходимо выбрать пункт Query Tool меню Tools. Описание задания База данных книготорговой компании Рассмотрим простую предметную область жизнедеятельности, связанную с книгоизданием и маркетингом. В рамках данной предметной области существуют издатели, которые публикуют книги, авторы, которые книги пишут, и издания (сами книги). Разработана база данных pubs, определяющая описанную выше предметную область. Инфологическая модель предметной области с использованием диаграмм “сущность-связь” (ER-диаграмм) [1]), разработанных Ченом, представлена на рис. 1. На данном рисунке прямоугольниками обозначены типы сущностей (объектов), а ромбами - типы связей между сущностями. Атрибуты сущностей указаны мелким шрифтом в том же прямоугольнике, который отображает типы сущностей. Имя типа сущности отмечено в верхней части прямоугольника жирным шрифтом. Атрибуты связей в данном случае обозначены овалами. Как видно из рис. 1 у связи “Написана” имеется два атрибута: первый атрибут определяет порядок автора в названии книги, второй атрибут гонорар автора книги. Рис. 1 База данных книготорговой компании (база данных pubs) включает три таблицы, определяющие сущности: таблица authors определяет авторов, таблица publishers издателей, а таблица titles - сами книги. Четвертая таблица titleauthor задает отношение между таблицами titles и authors. Она показывает, какие авторы написали какие книги. Связь между таблицами titiles и publishers определяется столбцом pub_id в данных таблицах. Ниже представлены структуры используемых таблиц. Структура таблицы authors Имя столбца Тип данных au_id au_lname au_fname phone address city state zip contract varchar varchar varchar char varchar varchar char char bit Размерность Возможность значений null 11 Нет 40 Нет 20 Нет 12 Нет 40 Да 20 Да 2 Да 5 Да 1 Нет Содержательное описание Идентификатор автора Фамилия автора Имя автора Номер телефона Адрес (улица, дом, квартира) Город проживания Штат проживания Энергичность Наличие контракта Структура таблицы publishers Имя столбца pub_id Тип данных char pub_name city state country varchar varchar char varchar Размерность Возможность Содержательное описание значений null 4 Нет Идентификатор издательства (издателя) 40 Да Название издательства (имя издателя) 20 Да Город 2 Да Штат 30 Да Страна Структура таблицы titles Имя столбца Тип данных title_id title type pub_id price advance varchar varchar char char money money Размерность Возможность значений null 6 Нет 80 Нет 12 Нет 4 Да 8 Да 8 Да royalty ytd_sales int int 4 4 Да Да notes varchar 200 Да Содержательное описание Идентификатор книги Название книги Тип книги Идентификатор издательства Цена Аванс (стоимость предварительной продажи) Гонорар Число книг, проданных в текущем году Замечания pubdate datetime 8 Нет Дата опубликования Структура таблицы titleauthor Имя столбца au_id title_id au_ord royaltyper Тип данных varchar varchar tinyint int Размерность Возможность значений null 11 Нет 6 Нет 1 Да 4 Да Содержательное описание Идентификатор автора книги Идентификатор книги Порядок автора в названии книги Авторский гонорар В столбце type таблицы titles используются следующие типы книг: business - книги по бизнесу, mod_cook - книги по современной кулинарии, popular_comp - книги по компьютерной тематике, psychology - книги по психологии, trad_cook - книги по традиционной кулинарии, UNDECIDED - неопределенный тип книги. В столбцах state таблиц authors и publishers используются следующие обозначения административных единиц США: CA - штат Калифорния, DC - округ Колумбия, IL - штат Иллинойс, IN - штат Индиана, KS -штат Канзас, MD - штат Мэриленд, MA - штат Массачусетс, MI - штат Мичиган, NY - штат Нью-Йорк, OR - штат Орегон, TN - штат Теннесси, TX - штатТехас, UT - штат Юта. В столбце country таблицы publishers используются следующие обозначения стран: France - Франция, Germany - Германия, USA - США. Домен городов, используемый в таблицах authors и publishers, включает города Ann Arbor, Berkeley, Boston, Chicago, Corvallis, Colevo, Dallas, Gary, Lawrence, Menlo Park, Munchen, Nashville, New York, Oakland, Palo Alto, Paris, Rockville, Salt Lake City, San Francisco, San Jose, Vacaville, Walnul Creek, Washington. Лабораторные задания типа А Дать содержательную интерпретацию SQL-запросам, выполнить их на SQL-сервере с использованием клиентских утилит Query Analyzer или SQL-EM, дать содержательную интерпретацию результатам выполнения SQL-запросов. 1. SELECT au_lname, au_fname FROM authors 2. SELECT au_lname, au_fname FROM authors ORDER BY au_lname 3. SELECT au_lname, au_fname FROM authors ORDER BY au_lname, au_fname 4. SELECT title_id, price, ytd_sales, price*ytd_sales 'ytd dollar sales' FROM titles ORDER BY price*ytd_sales 5. SELECT title_id, price, ytd_sales, price*ytd_sales 'ytd dollar sales' FROM titles ORDER BY price*ytd_sales DESC 6. SELECT title_id, type, ytd_sales FROM titles ORDER BY type ASC, ytd_sales DESC 7. SELECT AVG(price) FROM titles 8. SELECT DISTINCT type FROM titles ORDER BY type ASC 9. SELECT DISTINCT city FROM authors ORDER BY city DESC 10. SELECT DISTINCT state FROM authors ORDER BY state 11. SELECT DISTINCT country FROM publishers ORDER BY country DESC 12. SELECT AVG(price), AVG(DISTINCT price) FROM titles 13. SELECT * FROM titles 14. SELECT au_lname, au_fname FROM authors WHERE state= 'CA' 15. SELECT type, title_id, price FROM titles WHERE price*ytd_sales < advance 16. SELECT au_id, city, state FROM authors WHERE state= 'CA' OR city= 'Palo Alto' 17. SELECT title_id, price FROM titles WHERE price between $5 AND $15 18. SELECT title_id, price FROM titles WHERE type IN ('mod_cook', 'trad_cook', 'business') 19. SELECT au_lname, au_fname, city, state FROM authors WHERE city like 'San%' 20. SELECT type, title_id, price FROM titles WHERE title_id like 'B_2075' 21. SELECT type, title_id, price FROM titles WHERE title_id like 'B[AUN]7832' 22. SELECT AVG(price) 'AVG' FROM titles WHERE type= 'business' 23. SELECT AVG(price) 'avg', SUM(price) 'sum' FROM titles WHERE type IN ('business', 'mod_cook') 24. SELECT COUNT(*) FROM authors WHERE state= 'CA' 25. SELECT COUNT(*) FROM titles WHERE title LIKE 'Co%s' 26. SELECT title FROM titles WHERE ytd_sales IS NULL 27. SELECT au_lname 'Фамилия', au_fname 'Имя' FROM authors WHERE contract=1 AND phone LIKE '408____-__2_' 28. SELECT phone FROM authors WHERE address LIKE '%Broadway Av.%' 29. SELECT title, pubdate FROM titles WHERE pubdate>= 'Jun 9 1991 12:00AM' AND pubdate< '6/16/91' 30. SELECT type, AVG(price) 'avg', SUM(price) 'sum' FROM titles WHERE type IN ('business', 'psychology') GROUP BY type 31. SELECT type, pub_id, AVG(price) 'avg', SUM(price) 'sum' FROM titles WHERE type IN ('business', 'mod_cook') GROUP BY type, pub_id 32. SELECT type, AVG(price) FROM titles WHERE price>$11 GROUP BY type HAVING AVG(price)>$19.7 33. SELECT au_id, COUNT(*) FROM authors GROUP BY au_id HAVING COUNT(*)>1 34. SELECT type, MIN(price), MAX(price) FROM titles GROUP BY type ORDER BY type 35. SELECT type, MIN(price), MAX(price) FROM titles GROUP BY type HAVING MAX(price)-MIN(price)>=3 36. SELECT state, COUNT(DISTINCT pub_id) FROM publishers GROUP BY state 37. SELECT pub_name, AVG(price) 'avg', COUNT(DISTINCT title_id) 'count' FROM titles t JOIN publishers p ON t.pub_id=p.pub_id GROUP BY pub_name 38. SELECT type, (MIN(price)+MIN(price))/2, AVG(price) FROM titles GROUP BY type HAVING type<> 'UNDECIDED' ORDER BY 2 DESC 39. SELECT type, MIN(pubdate), MAX(pubdate) FROM titles GROUP BY type 40. SELECT title, pub_name FROM titles CROSS JOIN publishers 41. SELECT * FROM titles, publishers 42. SELECT title, pub_name FROM titles, publishers WHERE titles.pub_id=publishers.pub_id 43. SELECT title, pub_name FROM titles JOIN publishers ON titles.pub_id=publishers.pub_id 44. SELECT * FROM titles t, publishers p WHERE t.pub_id=p.pub_id 45. SELECT t.*, pub_name FROM titles t, publishers p WHERE t.pub_id=p.pub_id 46. SELECT a.city, a.state FROM authors a, publishers p WHERE a.city=p.city AND a.state=p.state 47. SELECT au_lname, au_fname FROM authors a JOIN titleauthor ta ON a.au_id=ta.au_id JOIN titles t ON ta.title_id=t.title_id WHERE au_lname LIKE 'R%' AND state IN ('CA', 'TX', 'NY', 'OR', 'UT') AND (title LIKE '_h_ %' OR title LIKE '% _h_ %' OR title LIKE '% _h_') 48. SELECT title, type FROM authors a, titles t, titleauthor ta, publishers p WHERE ta.title_id=t.title_id AND a.au_id=ta.au_id AND t.pub_id=p.pub_id AND p.city=a.city 49. SELECT au_lname, au_fname, title FROM authors a, titles t, titleauthor ta, publishers p WHERE ta.title_id=t.title_id AND a.au_id=ta.au_id AND t.pub_id=p.pub_id AND ((p.country= 'USA' AND t.type='popular_comp') OR (p.country='France' AND t.type='psychology')) 50. SELECT au_lname, au_fname, city FROM authors a, titles t, titleauthor ta WHERE ta.title_id=t.title_id AND a.au_id=ta.au_id AND (city LIKE '[CPR]%' OR city LIKE '%San%') AND (title LIKE '% the %' OR title LIKE 'The %' OR title LIKE '% a %' OR title LIKE 'A %') 51. SELECT DISTINCT au_lname, au_fname FROM authors a JOIN titleauthor ta ON a.au_id=ta.au_id JOIN titles t ON ta.title_id=t.title_id JOIN publishers p ON p.pub_id=t.pub_id WHERE p.state= 'CA' ORDER BY au_lname, au_fname 52. SELECT pub_name FROM publishers p JOIN titles t ON p.pub_id=t.pub_id WHERE $15>price AND type= 'psychology' ORDER BY pub_name 53. SELECT pub_name, AVG(price) FROM titles t, publishers p WHERE t.pub_id=p.pub_id GROUP BY pub_name 54. SELECT pub_name, AVG(price) FROM titles t JOIN publishers p ON t.pub_id=p.pub_id GROUP BY pub_name 55. SELECT au_lname, au_fname, title FROM authors a, titles t, titleauthor ta WHERE ta.title_id=t.title_id AND a.au_id=ta.au_id AND type= 'popular_comp' 56. SELECT au_lname, au_fname, title FROM authors a JOIN titleauthor ta ON a.au_id=ta.au_id JOIN titles t ON ta.title_id=t.title_id WHERE type= 'psychology' 57. SELECT au_lname, au_fname, pub_name, COUNT(*) FROM authors a, titles t, titleauthor ta, publishers p WHERE ta.title_id=t.title_id AND a.au_id=ta.au_id AND t.pub_id=p.pub_id GROUP BY au_lname, au_fname, pub_name 58. SELECT MIN(price) FROM titles t, publishers p WHERE t.pub_id=p.pub_id GROUP BY country HAVING country='USA' 59. SELECT pub_name, COUNT(*) FROM titles t, publishers p WHERE t.pub_id=p.pub_id AND (type= 'mod_cook' OR type='trad_cook') GROUP BY pub_name 60. SELECT pub_name, COUNT(*) FROM publishers p, titles t WHERE p.pub_id=t.pub_id AND price>$15 GROUP BY pub_name ORDER BY pub_name DESC 61. SELECT title, COUNT(DISTINCT a.au_id) FROM titles t JOIN titleauthor ta ON t.title_id=ta.title_id JOIN authors a ON ta.au_id=a.au_id JOIN publishers p ON p.pub_id=t.pub_id GROUP BY title 62. SELECT state, COUNT(DISTINCT p.pub_id) FROM publishers p JOIN titles t ON p.pub_id=t.pub_id GROUP BY state 63. SELECT title FROM titles WHERE pub_id= (SELECT pub_id FROM publishers WHERE pub_name= 'Binnet & Hardley') 64. SELECT pub_name FROM publishers WHERE pub_id IN (SELECT pub_id FROM titles WHERE type= 'business') 65. SELECT pub_name FROM publishers p WHERE EXISTS (SELECT * FROM titles t WHERE p.pub_id=t.pub_id AND type='popular_comp') 66. SELECT pub_name FROM publishers p WHERE NOT EXISTS (SELECT * FROM titles t WHERE p.pub_id=t.pub_id AND type='mod_cook') 67. SELECT pub_name FROM publishers WHERE pub_id NOT IN (SELECT pub_id FROM titles WHERE type='psychology') 68. SELECT type, price FROM titles WHERE price < (SELECT AVG(price) FROM titles) 69. SELECT type, AVG(price) FROM titles GROUP BY type HAVING AVG(price) < (SELECT AVG(price) FROM titles) 70. SELECT DISTINCT a.city, a.state FROM authors a WHERE NOT EXISTS (SELECT * FROM publishers p WHERE a.city=p.city AND a.state=p.state) 71. SELECT DISTINCT p.city, p.state FROM publishers p WHERE NOT EXISTS (SELECT * FROM authors a WHERE p.city=a.city AND p.state=a.state) 72. SELECT MIN(price) FROM titles t WHERE t.pub_id IN (SELECT pub_id FROM publishers WHERE country='USA') 73. SELECT title, type, price FROM titles WHERE price>ALL (SELECT price FROM titles WHERE type= 'psychology') 74. SELECT COUNT(DISTINCT city) FROM publishers WHERE pub_id IN (SELECT pub_id FROM titles WHERE type= 'psychology') 75. SELECT pub_name FROM publishers p WHERE 15>SOME (SELECT price FROM titles t WHERE p.pub_id=t.pub_id AND type= 'trad_cook') 76. SELECT pub_name, state FROM publishers WHERE pub_id NOT IN (SELECT pub_id FROM titles) 77. SELECT title FROM titles WHERE pub_id NOT IN (SELECT pub_id FROM publishers) 78. SELECT t.title FROM titles t WHERE t.price>= (SELECT AVG(tt.price) FROM titles tt GROUP BY tt.pub_id HAVING t.pub_id=tt.pub_id) 79. SELECT au_lname, au_fname, price FROM authors a, titles t, titleauthor ta, publishers p WHERE ta.title_id=t.title_id AND a.au_id=ta.au_id AND t.pub_id=p.pub_id AND country='USA' AND price= (SELECT MIN(price) FROM titles tt, publishers pp WHERE tt.pub_id=pp.pub_id GROUP BY country HAVING country='USA') 80. SELECT DISTINCT au_lname, au_fname FROM authors a, titles t, titleauthor ta WHERE a.au_id=ta.au_id AND ta.title_id IN (SELECT title_id FROM titles WHERE ytd_sales= (SELECT MAX(ytd_sales) FROM titles)) 81. SELECT DISTINCT a.city, a.state FROM authors a WHERE NOT EXISTS (SELECT * FROM publishers p WHERE a.city=p.city AND a.state=p.state) UNION SELECT DISTINCT p.city, p.state FROM publishers p WHERE NOT EXISTS (SELECT * FROM authors a WHERE p.city=a.city AND p.state=a.state) 82. SELECT title, price FROM titles t JOIN publishers p ON t.pub_id=p.pub_id WHERE p.country= 'USA' AND t.price= (SELECT MAX(price) FROM titles tt JOIN publishers pp ON tt.pub_id=pp.pub_id WHERE country= 'USA') 83. SELECT pub_name, COUNT(*) FROM titles t, publishers p WHERE t.pub_id=p.pub_id GROUP BY pub_name HAVING COUNT(*)>=ALL (SELECT COUNT(*) FROM titles tt, publishers pp WHERE tt.pub_id=pp.pub_id GROUP BY pub_name) 84. SELECT pub_name, city, state, country FROM publishers p WHERE EXISTS (SELECT * FROM titles t WHERE t.pub_id=p.pub_id) AND 20>ALL (SELECT price FROM titles t WHERE t.pub_id=p.pub_id AND price IS NOT NULL) 85. SELECT state, SUM(price) FROM titles t, publishers p WHERE t.pub_id=p.pub_id GROUP BY state HAVING state NOT IN ('TN', 'MA', 'TX') AND SUM(price)> (SELECT SUM(price) FROM titles tt, publishers pp WHERE tt.pub_id=pp.pub_id AND pp.city= 'Boston') 86. SELECT pub_name, MIN(price) FROM titles t, publishers p WHERE t.pub_id=p.pub_id GROUP BY pub_name HAVING MIN(price)>=ALL (SELECT MIN(price) FROM titles tt JOIN publishers pp ON tt.pub_id=pp.pub_id GROUP BY pub_name) 87. SELECT * FROM publishers WHERE pub_id IN (SELECT pub_id FROM titles WHERE type= 'psychology' AND pub_id IN (SELECT pub_id FROM publishers WHERE country= 'USA' AND state<> 'CA')) 88. SELECT au_lname, au_fname FROM authors a WHERE a.au_id IN (SELECT au_id FROM titleauthor ta WHERE ta.title_id IN (SELECT title_id FROM titles t WHERE 'CA'=SOME (SELECT state FROM publishers p WHERE p.pub_id=t.pub_id))) ORDER BY au_lname, au_fname 89. SELECT state, COUNT(*) FROM publishers p WHERE EXISTS (SELECT * FROM titles t WHERE p.pub_id=t.pub_id) AND $22>ALL (SELECT price FROM titles t WHERE p.pub_id=t.pub_id AND price IS NOT NULL) GROUP BY state ORDER BY state ASC 90. SELECT state FROM publishers p1 GROUP BY state HAVING COUNT(DISTINCT pub_name)= (SELECT COUNT(*) FROM publishers p2 WHERE EXISTS (SELECT * FROM titles t WHERE p2.pub_id=t.pub_id) AND $22.5>ALL (SELECT price FROM titles t WHERE p2.pub_id=t.pub_id AND price IS NOT NULL) GROUP BY state HAVING p1.state=p2.state) 91. SELECT p1.pub_id FROM titles t1, publishers p1 WHERE t1.pub_id=p1.pub_id GROUP BY p1.pub_id HAVING COUNT(DISTINCT title)= (SELECT COUNT(*) FROM titles t2 WHERE t2.pub_id=p1.pub_id AND EXISTS (SELECT * FROM titleauthor ta3, authors a3 WHERE ta3.au_id=a3.au_id AND ta3.title_id=t2.title_id AND a3.state IN (SELECT state FROM publishers p4 WHERE 'business'=SOME (SELECT type FROM titles t5 WHERE p4.pub_id=t5.pub_id)))) 92. SELECT city, state FROM authors UNION SELECT city, state FROM publishers ORDER BY state, city 93. SELECT city FROM authors UNION SELECT city FROM publishers 94. SELECT state FROM authors UNION SELECT state FROM publishers 95. SELECT city, state FROM authors WHERE state IS NOT NULL UNION SELECT city, state FROM publishers WHERE state IS NOT NULL ORDER BY city DESC, state ASC 96. SELECT state, MIN(price), MAX(price), AVG(price) FROM authors a, titles t, titleauthor ta WHERE ta.title_id=t.title_id AND a.au_id=ta.au_id GROUP BY state HAVING state<> 'CA' Лабораторные задания типа B Составить SQL-запросы по их заданному содержательному описанию, выполнить SQLзапросы на SQL-сервере с использованием клиентских утилит Query Analyzer или SQLEM, проинтерпретировать результаты выполнения запросов. 1. Выбрать имена и фамилии авторов книг. 2. Выбрать имена и фамилии авторов, проживающих в Калифорнии. 3. Выбрать информацию о книгах, объеме (стоимость) продаж которых в текущем году меньше стоимости предварительной продажи. Информация о книгах должна включать тип книги, идентификатор и цену книги. 4. Выбрать информацию об авторах, проживающих в штате Калифорния или в городе Salt Lake City. Информация об авторах должна включать идентификатор автора, город и штат проживания. 5. Выбрать все идентификаторы и цены книг, причем цена книги должна лежать в диапазоне от 5 до 10 долларов. В SQL запросе использовать предикат BETWEEN. 6. Выбрать все идентификаторы и цены книг по современной и традиционной кулинарии и по бизнесу. В запросе использовать предикат IN. 7. Выбрать информацию об авторах, проживающих в городах, название которых начинается со строки ‘spring’. Информация об авторах должна включать имя и фамилию автора, а также штат и город проживания. 8. Выбрать информацию о книгах, идентификаторы которых начинаются буквой ‘B’, а кончаются строкой ‘1342’. Информация о книгах должна включать тип, идентификатор и цену книги. 9. Выбрать информацию о книгах, идентификаторы которых начинаются буквой ‘B’, заканчиваются строкой ‘1342’, а вторым символом идентификатора являются буквы ‘A’, ‘U’ или ‘N’. Информация о книгах должна включать тип, идентификатор и цену книги. 10. Выбрать имена и фамилии всех авторов, упорядоченные по возрастанию фамилий авторов. 11. Выбрать имена и фамилии всех авторов, упорядоченные в первую очередь по возрастанию фамилий и, во вторую очередь, по возрастанию имен. 12. Выбрать информацию о книгах, упорядоченную по возрастанию объема продаж (по стоимости). Информация о книгах должна включать идентификатор, цену, объем продаж (по количеству) и объем продаж (по стоимости). 13. То же, что 12, но использовать упорядочение по убыванию. 14. Выбрать информацию о всех книгах, упорядоченную по убыванию типа книги и числа проданных книг. Информация о книгах должна включать идентификатор и тип книги, а также число проданных книг. 15. Определить среднюю цену книги. 16. Определить среднюю цену книг по бизнесу. 17. Определить среднюю цену и стоимость всех книг по бизнесу и современной кулинарии 18. Определить число авторов, проживающих в Калифорнии. 19. Определить среднюю цену и сумму цен на книги по бизнесу и современной кулинарии отдельно для каждого типа книги. 20. Определить среднюю цену и сумму цен на книги по бизнесу и современной кулинарии для каждой комбинации типа книги и идентификатора издателя. 21. Выбрать те типы книг, средняя цена дорогих экземпляров (стоимостью более 10 долларов) которых превышает 20 долларов. В выбираемые данные помимо типа книги включить и среднюю цену дорогих экземпляров. 22. Подсчитать число строк в таблице authors, включающих одинаковые идентификаторы авторов. В выбираемые данные включить идентификатор автора и соответствующее ему число повторяющихся строк. 23. Выбрать названия книг и имена выпустивших их издателей. 24. То же, что и 23, но в разделе FROM запроса использовать операцию соединения JOIN. 25. Произвести проекцию на столбцы title и pub_name декартова произведения таблиц titles и publishers. 26. Определить среднюю цену выпускаемых каждым издателем книг. В выбираемые данные включить имя издателя и среднюю цену книги. 27. То же, что и 26, но в разделе FROM запроса использовать операцию соединения JOIN. 28. Определить, кто из авторов написал какую книгу по психологии. В выбираемые данные включить имя и фамилию автора, а также название книги. 29. То же, что и 28, но в разделе FROM запроса использовать операцию соединению JOIN. 30. Выбрать все столбцы результата эквисоединения таблиц titles publishers по идентификатору издателя. 31. Выбрать все столбцы таблицы titles и столбец pub_name таблицы publishers результата эквисоединения данных таблиц по идентификатору издателя. 32. Выбрать все книги издательства Algodata Infosysytems. В запросе использовать подзапрос для определения нужного идентификатора издателя. В условии поиска использовать предикат ‘=‘. В выбираемые данные включить название книги. 33. Выбрать всех издателей литературы по бизнесу. В запросе использовать подзапрос для выборки нужных идентификаторов издателей. В условии поиска использовать предикат IN. В выбираемые данные включить имя издателя. 34. Выбрать всех издателей литературы по бизнесу. В запросе использовать подзапрос, формирующий промежуточную таблицу, в которую включаются те строки из таблицы titles, которые могут “экви-соединиться” по идентификатору издателя со строками из таблицы publishers и которые представляют тип книг по бизнесу. В условии поиска основного запроса использовать предикат EXISTS. В выбираемые данные включить имя издателя. 35. Выбрать издателей, не выпускающих книг по бизнесу. Дополнительные условия формирования запроса взять из варианта 34. 36. Выбрать издателей, не выпускающих книг по бизнесу. Дополнительные условия формирования запроса взять из варианта 33. 37. Выбрать тип и цену для всех книг, цена которых не превышает средней. В запросе использовать подзапрос, определяющий среднюю цену книг. 38. Выбрать тип и среднюю цену книг данного типа, причем эта средняя цена должна быть меньше средней цены всех книг. В запросе использовать подзапрос, определяющий среднюю цену всех книг. 39. Определить города и штаты проживания каждого из авторов и издателей в виде одной результирующей таблицы. 40. Определить все типы книг. Типы книг в результирующей таблице не должны повторяться. Вывести типы книг в порядке возрастания. 41. Определить все города, в которых проживают авторы. Названия городов в результирующей таблице не должны повторяться. Вывести названия городов в порядке убывания. 42. Определить все штаты, в которых проживают авторы. Названия штатов в результирующей таблице не должны повторяться. Вывести названия штатов в порядке возрастания. 43. Определить страны, в которых расположены издательства книг. Названия стран в результирующей таблице не должны повторяться. Вывести названия стран в порядке убывания. 44. Определить все города, в которых проживают авторы и находятся издательства. Названия городов в результирующей таблице не должны повторяться. Вывести названия городов в порядке возрастания. 45. Определить все штаты, в которых проживают авторы и находятся издательства. Названия штатов в результирующей таблице не должны повторяться. Вывести названия штатов в порядке убывания. 46. Определить города и штаты совместного проживания авторов и издателей. (В запросе неявно реализуется операцию пересечения). 47. Определить города и штаты проживания авторов, в которых нет издательств. (В запросе неявно реализуется операция разности). 48. Определить города и штаты нахождения издательств, в которых не проживают авторы. (В запросе неявно реализуется операция разности). 49. Определить, какой город в каком штате находится. Вывести названия городов в порядке возрастания. 50. Определить число книг, название которых начинается со строки ‘The’ и заканчивается буквой ‘e’. 51. Определить авторов на букву ‘G’, проживающих в штатах Теннесси, Иллинойс, Канзас, Орегон или Калифорния, которые опубликовали книги, в которых есть слово из трех букв, причем средней буквой является буква ‘a’. 52. Определить минимальную, максимальную и среднюю цену для каждого из типов книг. Выводимые данные должны быть упорядочены по убыванию типа книг. 53. Определить минимальную и максимальную цену для каждого из типов книг. В результирующую таблицу не включать те типы книг, для которых разность между максимальной и средней ценой меньше 7 долларов. 54. Вычислить среднюю цену всех книг и медиану цены. Под медианой понимается среднее значение всех различных цен всех книг. 55. Определить, какие авторы в каких издательствах опубликовали сколько книг. 56. Определить книги, авторы и издатели которых живут в одном городе. 57. Определить для каждого штата минимальную, максимальную и среднюю цену книг авторов, проживающих в одном штате (кроме штата Калифорния). 58. Определить, какие авторы опубликовали какие книги в США по традиционной кулинарии или в Германии по компьютерам. 59. Найти цену самой дешевой книги (книг), вышедшей в США. В запросе использовать операцию группирования. 60. Найти авторов самых дорогих книг, вышедших в США. В запросе использовать подзапрос и операцию группирования. 61. Найти авторов, у которых вышли самые нераспродаваемые книги. 62. Найти цену самой дорогой книги (книг), вышедшей в США. В запросе использовать подзапрос. 63. Определить число книг по компьютерам, выпущенных каждым издательством. 64. Определить авторов из городов, начинающихся с букв ‘A’, ‘B’ или ‘C’ или имеющих в своем составе слово ‘Salt’, и написавших книги, в названии которых есть определенный или неопределенный артикль английского языка. 65. Определить города и штаты проживания авторов и издателей, за исключением городов и штатов их совместного проживания. (В запросе неявно реализуется операция симметрической разности). 66. Определить названия и цену самых дешевых книг, вышедших в США. (Самые дешевые книги имеют минимальную цену). 67. Определить издательство, в котором опубликовано меньше всего книг. 68. Найти книги, цена которых меньше цены каждой из книг по традиционной кулинарии. 69. Определить местонахождение издательств, цена каждой книги которых меньше 22 долларов. В запросе использовать подзапросы и предикат с квантором. 70. Определить штаты (кроме штатов Индиана, Канзас, Юта), в которых сумма цен выпущенных в них книг больше суммы цен книг, выпущенных в городе Вашингтон. 71. Найти издательство, выпустившее свою самую дорогую книгу с наиболее низкой ценой среди всех издательств. В запросе использовать подзапрос, определяющий максимальные цены книг, выпущенные каждым издательством. 72. Определить полную информацию об издателях книг по компьютерам, авторы которых живут в США (за исключением штата Юта). В запросе использовать подзапросы. 73. Определить книги, стоимости которых составляют не более средней стоимости по издательству, где издавались эти книги. 74. Определить для каждого штата число находящихся в нем издательств. 75. Определить число городов, в которых выпускается литература по компьютерам. В запросе использовать подзапрос. 76. Определить авторов, хотя бы одна книга которых была опубликована в штате Массачусетс. В запросе использовать подзапросы и предикат с квантором. 77. Найти издательства, среди изданных книг которых найдется хоть одна книга по компьютерам стоимостью более двух долларов. В запросе использовать подзапрос и предикат с квантором. 78. Определить штаты, во всех издательствах которых все изданные книги имеют цену более 10 долларов. В запросе использовать подзапросы и предикат с квантором. 79. Определить издательства, для каждой книги которых выполняется условие: “Если книга выпущена в данном издательстве, то хотя бы один из авторов книги проживает в штате, в котором находится издательство, некоторые выпущенные книги которого посвящены компьютерам”. 80. Выбрать все столбцы таблицы titles. 81. Выбрать все столбцы декартова произведения таблиц titles и publishers. 82. Определить книги, число продаж для которых неопределено. 83. Определить минимальную и максимальную цену книг, выпущенных издательствами. 84. Определить авторов, хотя бы одна книга которых была опубликована в штате Массачусетс. В запросе не использовать предикаты с квантором. 85. Найти издательства, среди изданных книг которых найдется хоть одна книга по традиционной кулинарии стоимостью от 12 до 16 долларов. В запросе не использовать предикаты с квантором. 86. Определить для каждого издательства число изданных им дешевых книг (ценой менее 13 долларов). 87. Определить для штатов число издательств, в которых выпускаются только книги ценой более 7 долларов. В запросе использовать подзапросы и предикат с квантором. 88. Определить, сколько авторов имеет каждая изданная книга. 89. Определить штаты и число находящихся в них издательств, выпустивших книги. 90. Определить издательства, не выпустившие книг. 91. Определить неопубликованные в издательствах книги. 92. Определить авторов, работающих по контракту и имеющих телефон с кодом города 415 (первые три цифры номера телефона). 93. Определить номера телефонов авторов, проживающих на Седьмой Авеню (Seventh Av.) 94. Определить книги, выпущенные в период с 1 июля 1991 г. по 30 октября 1991 г. (По умолчанию сервер работает с датами в формате xx/yy/zz как с последовательностями месяц/день/год). 95. Вычислить для каждого типа книг среднее арифметическое минимальной и максимальной цены. Результат упорядочить по убыванию значений. 96. Определить временные интервалы, в рамках которых опубликованы книги разных типов. Примечания: 1. При упорядочении фамилий и имен авторов, городов, штатов, типов книг используется лексикографический порядок.2. “Издатель” и “издательство” являются в данном случае синонимами. Соответственно этому синонимами являются “имя издателя” и “название издательства”. Варианты лабораторных заданий Номер варианта 1 2 3 4 5 6 7 8 9 10 11 12 01 02 03 04 05 06 08 09 10 11 07 12 13 14 15 16 17 18 19 20 21 22 24 23 Задание типа A 25 32 49 73 26 38 50 62 27 39 51 61 28 37 46 59 29 41 57 66 30 42 58 67 31 52 53 70 34 44 55 71 35 40 45 56 33 47 68 72 36 43 69 76 48 54 60 74 81 63 64 65 84 83 80 79 75 77 78 85 96 86 90 91 92 93 94 95 82 88 89 87 09 08 07 17 15 16 03 02 01 06 05 04 25 28 20 27 18 22 11 10 21 14 13 12 Задание типа B 29 31 42 53 30 41 48 49 26 40 45 47 54 56 70 72 24 38 73 74 37 43 51 62 33 78 84 88 32 64 71 82 50 57 58 65 19 23 36 44 35 39 55 69 35 46 63 79 66 52 61 75 87 76 92 89 68 59 81 83 77 60 85 86 90 91 96 95 80 67 94 93