-
Главная
-
Туториалы
-
Базы данных
- SQL
SQL-псевдонимы используются для предоставления таблицы или столбца таблицы временного имени.
Псевдонимы часто используются, чтобы сделать имена столбцов более читабельными. Псевдоним существует только для продолжительности запроса.
Псевдонимы могут быть полезны, когда:
- В запросе содержится более одной таблицы
- Функции используются в запросе
- Названия столбцов большие или не очень читаемые
- Два или более столбца объединяются вместе
SELECT column_name AS alias_name
FROM table_name;
Синтаксис таблицы псевдонимов
SELECT column_name(s)
FROM table_name AS alias_name;
Псевдоним для столбцов
Следующий оператор SQL создает два псевдонима: один для столбца user_id и один для столбца name:
Пример:
SELECT user_id as ID, name AS user
FROM users;
Следующий оператор SQL создает два псевдонима: один для столбца name и один для столбца address.
Пример:
SELECT name AS user, address AS [Address User]
FROM users;
Псевдонимы для таблиц
Следующий оператор SQL выбирает все счета от пользователя с помощью user_id и name. В запросе используются таблицы «users» и «invoice», которым даются псевдонимы таблиц «u» и «o».
Пример:
SELECT i.invoice_id, i.date, i.name
FROM users AS u, invoice AS i
WHERE u.name = "Том" AND u.user_id = i.user_id;
В этом учебном материале вы узнаете, как использовать SQL псевдонимы (временные имена для столбцов или таблиц) с синтаксисом и примерами.
Описание
SQL ALIASES можно использовать для создания временного имени для столбцов или таблиц.
- Псевдонимы столбцов используются для облегчения чтения заголовков столбцов в наборе результатов.
- Псевдонимы таблиц используются для сокращения вашего SQL-кода, чтобы его было легче читать или когда вы выполняете самосоединение (т.е. перечисление одной и той же таблицы более одного раза в операторе FROM).
Синтаксис
Синтаксис псевдонима столбца в SQL:
column_name [AS] alias_name
Или
Синтаксис псевдонима таблицы в SQL:
table_name [AS] alias_name
Параметры или аргументы
- column_name
- оригинальное имя столбца, которому вы хотите указать псевдоним.
- table_name
- оригинальное имя таблицы, которой вы хотите указать псевдоним.
- alias_name
- псевдоним для назначения.
Примечание
- Если alias_name содержит пробелы, вы должны заключить alias_name в кавычки.
- При псевдониме имени столбца допустимо использовать пробелы. Однако обычно не рекомендуется использовать пробелы при создании псевдонимов имени таблицы.
- alias_name действителен только в рамках SQL оператора.
Пример — псевдоним имени столбца
Обычно псевдонимы используются для облегчения чтения заголовков столбцов в наборе результатов. Чаще всего вы будете использовать псевдоним столбца при использовании в запросе статистической функции, такой как MIN, MAX, AVG, SUM или COUNT.
Давайте рассмотрим пример использования псевдонима имени столбца в SQL.
В этом примере у нас есть таблица employees со следующими данными:
employee_number | first_name | last_name | salary | dept_id |
---|---|---|---|---|
1001 | Justin | Bieber | 62000 | 500 |
1002 | Selena | Gomez | 57500 | 500 |
1003 | Mila | Kunis | 71000 | 501 |
1004 | Tom | Cruise | 42000 | 501 |
Продемонстрируем, как создать псевдоним столбца. Введите следующий SQL оператор:
SELECT dept_id, COUNT(*) AS total FROM employees GROUP BY dept_id; |
Будет выбрано 2 записи. Вот результаты, которые вы получите:
dept_id | total |
---|---|
500 | 2 |
501 | 2 |
В этом примере мы для COUNT(*) использовали псевдоним total. В результате итоговое значение будет отображаться в качестве заголовка для второго столбца при возврате набора результатов. Поскольку в нашем псевдониме не было пробелов, нам не нужно заключать псевдоним в кавычки.
Теперь давайте перепишем наш запрос, чтобы включить пробел в псевдоним столбца:
SELECT dept_id, COUNT(*) AS «total employees» FROM employees GROUP BY dept_id; |
Будет выбрано 2 записи. Вот результаты, которые вы получите:
dept_id | total employees |
---|---|
500 | 2 |
501 | 2 |
В этом примере мы добавили в поле COUNT(*) псевдоним «total employees», поэтому он станет заголовком для второго столбца в нашем наборе результатов. Поскольку в псевдониме этого столбца есть пробелы, «total employees» должны быть заключены в кавычки в операторе SQL.
Пример псевдоним для имени таблицы
Когда вы создаете псевдоним таблицы, это происходит потому, что вы планируете перечислить одно и то же имя таблицы более одного раза в FROM, или вы хотите сократить имя таблицы, чтобы сделать SQL оператор короче и проще для чтения.
Давайте рассмотрим пример псевдонима имени таблицы в SQL.
В этом примере у нас есть таблица products со следующими данными:
product_id | product_name | category_id |
---|---|---|
1 | Pear | 50 |
2 | Banana | 50 |
3 | Orange | 50 |
4 | Apple | 50 |
5 | Bread | 75 |
6 | Sliced Ham | 25 |
7 | Kleenex | NULL |
И таблица с именем categories со следующими данными:
category_id | category_name |
---|---|
25 | Deli |
50 | Produce |
75 | Bakery |
100 | General Merchandise |
125 | Technology |
Теперь давайте объединим эти 2 таблицы и псевдонимы каждого из имен таблиц. Введите следующий SQL оператор:
SELECT p.product_name, c.category_name FROM products AS p INNER JOIN categories AS c ON p.category_id = c.category_id WHERE p.product_name <> ‘Pear’; |
Будет выбрано 5 записей. Вот результаты, которые вы получите:
product_name | category_name |
---|---|
Banana | Produce |
Orange | Produce |
Apple | Produce |
Bread | Bakery |
Sliced Ham | Deli |
В этом примере мы создали псевдоним для таблицы products и псевдоним для таблицы category. Теперь в рамках этого SQL оператора мы можем ссылаться на таблицу products как p, а на таблицу category — как c.
При создании псевдонимов таблиц нет необходимости создавать псевдонимы для всех таблиц, перечисленных в предложении FROM. Вы можете создать псевдонимы для любой или всех таблиц.
Построение таблиц в реляционной БД
- Создайте новую базу данных Кафе.
Таблицы ^ и Заказано постройте с помощью конструктора.
- Запишите SQL—запрос для создания таблицы Заказы и выполните его:
Ответ:
- Установите связи между таблицами:
- Заполните таблицы данными из §14 (рис. 3.16). Можно добавить и свои данные. Таблицу Заказы заполните с помощью SQL-запросов. Запишите эти запросы в следующем поле:
Ответ:
- ^
- Постройте простой запрос ЗапросЗаказы, который собирает всю информацию о составе сделанных заказов. Как выглядит этот запрос на языке SQL?
Ответ:
- Объясните, как на языке SQL учитываются связи между таблицами?
Ответ:
- Задайте псевдонимы (подписи) для столбцов запроса. Как псевдонимы изменили SQL-запрос?
Ответ:
- Постройте итоговый запрос ЗапросКОплате, который подсчитывает общую сумму оплату по каждому из сделанных заказов. Как выглядит этот запрос на языке SQL?
Ответ:
- Объясните, как выполняется на языке SQL суммирование цен отдельных блюд?
Ответ:
- Объясните, что означают ключевые слова GROUP BY на языке SQL?
Ответ:
^
В этой работе вы познакомитесь с новой командой ALTER TABLE (изменить таблицу) языка SQL и научитесь составлять запросы к многотабличной реляционной базе данных.
^
- Используя только SQL-запросы, постройте три таблицы для реляционной базы данных кафе (значок
обозначает первичный ключ таблицы):
- Теперь нужно построить связи между таблицами:
Для этой цели используется команда ^ (англ. изменить таблицу). Построить связь между таблицами – это значит задать ограничение (CONSTRAINT), которое связывает первичный ключ одной таблицы с полем соответствующего типа другой. Если связываемое поле второй таблицы – неключевое, то оно называется внешним ключом (^ ). Например, команда для создания связи 1:N между ключевым полем Номер таблицы Заказы и неключевым полем Номер заказа таблицы Заказано выглядит так:
ALTER TABLE «Заказано»
^
FOREIGN KEY(«Номер заказа»)
REFERENCES «Заказы»(«Номер»)
Такая запись дословно означает:
Изменить таблицу «Заказано»
добавить связь ORDER_NO
внешний ключ «Номер заказа»
ссылается на поле «Номер» таблицы «Заказы»
Здесь ORDER_NO – это просто имя, которое мы выбрали для этой связи (можно было выбрать и другое).
- Введите и выполните показанный выше SQL-запрос на добавление связи. Зайдите в меню Сервис – Связи и убедитесь, что связь действительно создана4.
- Составьте и выполните SQL-запрос на добавление второй связи. Запишите этот запрос в поле для ответа.
Ответ:
- С помощью SQL-запросов заполните базу следующими данными
^
Выбор данных и сортировка
- Построим в режиме SQL запрос СоставЗаказа, который выводит номер заказа и название заказанных блюд. Эти данные находятся в двух таблицах – Заказано и Блюда, поэтому их нужно как-то объединить. Для этого используется связь 1:N между таблицами, которую мы недавно установили. Действительно, для каждой записи в таблице Заказано нужно выбрать название блюда из таблицы Блюда, код которого совпадает с полем Заказано.Код блюда.
Это запрос на выборку данных, поэтому используем оператор ^ :
SELECT «Заказано».»Номер заказа», «Блюда».»Название»
FROM «Заказано», «Блюда»
WHERE «Заказано».»Код блюда» = «Блюда».»Код»
Здесь из таблиц Заказано и Блюда выбираются поля Номер заказа и Название; условие в последней строке связывает таблицы.
Поскольку названия полей в таблицах, из которых идет выбор, не совпадают, можно было записать запрос в сокращенной форме, указав после оператора SELECT только названия нужных полей:
^
FROM «Заказано», «Блюда»
WHERE «Заказано».»Код блюда» = «Блюда».»Код»
- Теперь добавим в запрос дату заказа. Она находится в таблице Заказы, которая пока в запросе не участвует. Таким образом, нам нужно объединить три таблицы. Условие отбора получается сложным, два условия (связи по коду блюда между таблицами Заказано и Блюда и по номеру заказа между таблицами Заказы и Заказано) объединяются с помощью логической операции AND (И):
^
FROM «Заказано», «Блюда», «Заказы»
WHERE «Заказано».»Код блюда» = «Блюда».»Код»
AND «Заказано».»Номер заказа» = «Заказы».»Номер»
Проверьте результат выполнения этого запроса.
- Измените запрос так, чтобы он выбирал только блюда из состава заказа № 1. Запишите этот запрос:
Ответ:
- Построим еще один запрос Итоги, в котором для каждого заказа выводится его номер, дата и общая сумма (с помощью функции ^ ).
SELECT «Номер заказа», «Дата», SUM(«Цена»)
FROM «Заказано», «Блюда», «Заказы»
WHERE «Заказано».»Код блюда» = «Блюда».»Код»
AND «Заказано».»Номер заказа» = «Заказы».»Номер»
^
В последней строке указано, что по полям Номер заказа и Дата выполняется группировка, то есть сумма цен считается для каждой уникальной пары «Номер заказа – Дата».
В таблице с результатами запроса заголовок столбца с суммой выглядит не совсем понятно для пользователя:
«SUM(«Блюда».»Цена»)»
Для того, чтобы сделать у этого столбца заголовок «Сумма», нужно добавить в первую строку запроса после SUM(«Цена») так называемый псевдоним (подпись) с ключевым словом AS:
^
…
Проверьте результат выполнения этого запроса. Псевдонимы можно задавать для всех значений, которые выводятся в запросе.
- Измените запрос так, чтобы заказы были отсортированы в порядке убывания суммы (используйте ключевые слова ORDER BY).
Ответ:
^
Вложенные запросы
- Построим запрос МинСумма, который выводит минимальную сумму заказа. Для этого будем использовать уже готовый запрос Итоги. Таким образом, источником данных для запроса МинСумма будет не таблица, а другой запрос. Отметим, что предварительно в запросе Итоги нужно отменить сортировку. Запрос получается очень простым
^
- Наконец, можно вывести информацию о заказе с минимальной суммой:
SELECT «Номер заказа», «Дата», «Сумма»
FROM «Итоги», «МинСумма»
WHERE «Итоги».»Сумма» = «МинСумма».»Сумма»
Обратите внимание, что этот запрос использует результаты выполнения двух ранее построенных запросов – ^ и МинСумма. Запрос Итоги можно было и не составлять, а вместо этого использовать вложенный запрос (запрос в запросе):
SELECT «Номер заказа», «Дата», «Сумма»
FROM «Итоги»
WHERE «Сумма» =
(SELECT MIN(«Сумма») AS «Сумма» FROM «Итоги»)
Заметим, что если в базе данных есть информация о нескольких заказах с такой же (минимальной) суммой, будет показана информация обо всех этих заказах.
- Измените запрос так, чтобы получить список всех заказов, сумма которых больше средней.
Ответ:
Алиасы
Псевдонимы SQL используются для присвоения таблице или столбцу в таблице временного имени.
Псевдонимы часто используются для того, чтобы сделать имена столбцов более удобочитаемыми.
Псевдоним существует только на время выполнения запроса.
Синтаксис столбца Алиас
SELECT column_name AS alias_name
FROM table_name;
Синтаксис таблиц Алиас
SELECT column_name(s)
FROM table_name AS alias_name;
Демо база данных
В этом уроке мы будем использовать хорошо известный пример базы данных Northwind.
Ниже приведен выбор из таблицы «Customers»:
CustomerID | CustomerName | ContactName | Address | City | PostalCode | Country |
---|---|---|---|---|---|---|
2 | Ana Trujillo Emparedados y helados | Ana Trujillo | Avda. de la Constitución 2222 | México D.F. | 05021 | Mexico |
3 | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México D.F. | 05023 | Mexico |
4 | Around the Horn | Thomas Hardy | 120 Hanover Sq. | London | WA1 1DP | UK |
И выбор из таблицы «Orders»:
OrderID | CustomerID | EmployeeID | OrderDate | ShipperID |
---|---|---|---|---|
10354 | 58 | 8 | 1996-11-14 | 3 |
10355 | 4 | 6 | 1996-11-15 | 1 |
10356 | 86 | 6 | 1996-11-18 | 2 |
Примеры Алиас для столбцов
Следующий оператор SQL создает два псевдонима, один для столбца «CustomerID» и «CustomerName» для колонки:
Пример
SELECT CustomerID AS ID, CustomerName AS Customer
FROM Customers;
Попробуйте сами »
Следующий оператор SQL создает два псевдонима, один для CustomerName колонки и для столбцов ContactName.
Примечание: Он требует двойных кавычек или квадратных скобок, если имя псевдонима содержит пробелы:
Пример
SELECT CustomerName AS Customer, ContactName AS [Contact Person]
FROM Customers;
Попробуйте сами »
Следующий оператор SQL создает псевдоним «Address», которые объединяют четыре колонны (Address, PostalCode, City и Country):
Пример
SELECT CustomerName, Address + ‘, ‘ + PostalCode + ‘ ‘ + City + ‘, ‘ + Country
AS Address
FROM Customers;
Попробуйте сами »
Примечание: Чтобы получить инструкцию SQL, чтобы работать в MySQL использовать следующие:
SELECT CustomerName, CONCAT(Address,’, ‘,PostalCode,’, ‘,City,’, ‘,Country) AS Address
FROM Customers;
Пример Алиас для таблиц
Следующая инструкция SQL выбирает все заказы от клиента с CustomerID=4 (вокруг рожка).
Мы используем таблицы «Customers» и «Orders» и даем им псевдонимы таблиц
«c» и «o» соответственно (здесь мы используем псевдонимы, чтобы сделать SQL короче):
Пример
SELECT o.OrderID, o.OrderDate, c.CustomerName
FROM Customers AS c, Orders AS o
WHERE c.CustomerName=»Around the Horn» AND c.CustomerID=o.CustomerID;
Попробуйте сами »
Следующий оператор SQL такой же, как и выше, но без псевдонимов:
Пример
SELECT Orders.OrderID, Orders.OrderDate, Customers.CustomerName
FROM Customers, Orders
WHERE Customers.CustomerName=»Around the Horn» AND Customers.CustomerID=Orders.CustomerID;
Попробуйте сами »
Алиасы могут быть полезны, когда:
- В запросе участвует несколько таблиц
- В запросе используются функции
- Имена столбцов большие или не очень читаемые
- Две или более колонн объединяются вместе
Проверьте себя с помощью упражнений
Упражнение:
При отображении таблицы Customers
,
сделайте псевдоним столбца PostalCode
,
вместо этого столбец должен называться Pno
.
SELECT CustomerName, Address, PostalCode FROM Customers;
Начните упражнение
Упражнения
ПОДЕЛИТЬСЯ
Построение таблиц в реляционной БД
- Создайте новую базу данных Кафе.
Таблицы Блюда и Заказано постройте с помощью конструктора.
- Запишите SQL—запрос для создания таблицы Заказы и выполните его:
Ответ:
Примечание. Тип «дата» на языке SQL записывается как DATE.
- Установите связи между таблицами:
- Заполните таблицы данными из §14 (рис. 3.16). Можно добавить и свои данные. Таблицу Заказы заполните с помощью SQL-запросов. Запишите эти запросы в следующем поле:
Ответ:
Примечание. Дата 03.11.2014 вводится на языке SQL следующим образом:
– в OpenOffice Base как ‘2014-11-03’;
– в русской версии Microsoft Access как ‘03.11.2014’.
-
Создание запросов к реляционной базе данных
- Постройте простой запрос ЗапросЗаказы, который собирает всю информацию о составе сделанных заказов. Как выглядит этот запрос на языке SQL?
Ответ:
- Объясните, как на языке SQL учитываются связи между таблицами?
Ответ:
- Задайте псевдонимы (подписи) для столбцов запроса. Как псевдонимы изменили SQL-запрос?
Ответ:
- Постройте итоговый запрос ЗапросКОплате, который подсчитывает общую сумму оплату по каждому из сделанных заказов. Как выглядит этот запрос на языке SQL?
Ответ:
- Объясните, как выполняется на языке SQL суммирование цен отдельных блюд?
Ответ:
- Объясните, что означают ключевые слова GROUP BY на языке SQL?
Ответ:
Практическая работа № 20-SQL.
Язык SQL (многотабличная база данных, OpenOffice Base)
В этой работе вы познакомитесь с новой командой ALTER TABLE (изменить таблицу) языка SQL и научитесь составлять запросы к многотабличной реляционной базе данных.
Создание и заполнение таблиц
- Используя только SQL-запросы, постройте три таблицы для реляционной базы данных кафе (значок
обозначает первичный ключ таблицы):
- Теперь нужно построить связи между таблицами:
Для этой цели используется команда ALTER TABLE (англ. изменить таблицу). Построить связь между таблицами – это значит задать ограничение (CONSTRAINT), которое связывает первичный ключ одной таблицы с полем соответствующего типа другой. Если связываемое поле второй таблицы – неключевое, то оно называется внешним ключом (FOREIGN KEY). Например, команда для создания связи 1:N между ключевым полем Номер таблицы Заказы и неключевым полем Номер заказа таблицы Заказано выглядит так:
ALTER TABLE «Заказано»
ADD CONSTRAINT ORDER_NO
FOREIGN KEY(«Номер заказа»)
REFERENCES «Заказы»(«Номер»)
Такая запись дословно означает:
Изменить таблицу «Заказано»
добавить связь ORDER_NO
внешний ключ «Номер заказа»
ссылается на поле «Номер» таблицы «Заказы»
Здесь ORDER_NO – это просто имя, которое мы выбрали для этой связи (можно было выбрать и другое).
- Введите и выполните показанный выше SQL-запрос на добавление связи. Зайдите в меню Сервис – Связи и убедитесь, что связь действительно создана4.
- Составьте и выполните SQL-запрос на добавление второй связи. Запишите этот запрос в поле для ответа.
Ответ:
- С помощью SQL-запросов заполните базу следующими данными
Выбор данных и сортировка
- Построим в режиме SQL запрос СоставЗаказа, который выводит номер заказа и название заказанных блюд. Эти данные находятся в двух таблицах – Заказано и Блюда, поэтому их нужно как-то объединить. Для этого используется связь 1:N между таблицами, которую мы недавно установили. Действительно, для каждой записи в таблице Заказано нужно выбрать название блюда из таблицы Блюда, код которого совпадает с полем Заказано.Код блюда.
Это запрос на выборку данных, поэтому используем оператор SELECT:
SELECT «Заказано».»Номер заказа», «Блюда».»Название»
FROM «Заказано», «Блюда»
WHERE «Заказано».»Код блюда» = «Блюда».»Код»
Здесь из таблиц Заказано и Блюда выбираются поля Номер заказа и Название; условие в последней строке связывает таблицы.
Поскольку названия полей в таблицах, из которых идет выбор, не совпадают, можно было записать запрос в сокращенной форме, указав после оператора SELECT только названия нужных полей:
SELECT «Номер заказа», «Название»
FROM «Заказано», «Блюда»
WHERE «Заказано».»Код блюда» = «Блюда».»Код»
- Теперь добавим в запрос дату заказа. Она находится в таблице Заказы, которая пока в запросе не участвует. Таким образом, нам нужно объединить три таблицы. Условие отбора получается сложным, два условия (связи по коду блюда между таблицами Заказано и Блюда и по номеру заказа между таблицами Заказы и Заказано) объединяются с помощью логической операции AND (И):
SELECT «Номер заказа», «Дата», «Название»
FROM «Заказано», «Блюда», «Заказы»
WHERE «Заказано».»Код блюда» = «Блюда».»Код»
AND «Заказано».»Номер заказа» = «Заказы».»Номер»
Проверьте результат выполнения этого запроса.
- Измените запрос так, чтобы он выбирал только блюда из состава заказа № 1. Запишите этот запрос:
Ответ:
- Построим еще один запрос Итоги, в котором для каждого заказа выводится его номер, дата и общая сумма (с помощью функции SUM).
SELECT «Номер заказа», «Дата», SUM(«Цена»)
FROM «Заказано», «Блюда», «Заказы»
WHERE «Заказано».»Код блюда» = «Блюда».»Код»
AND «Заказано».»Номер заказа» = «Заказы».»Номер»
GROUP BY «Номер заказа», «Дата»
В последней строке указано, что по полям Номер заказа и Дата выполняется группировка, то есть сумма цен считается для каждой уникальной пары «Номер заказа – Дата».
В таблице с результатами запроса заголовок столбца с суммой выглядит не совсем понятно для пользователя:
«SUM(«Блюда».»Цена»)»
Для того, чтобы сделать у этого столбца заголовок «Сумма», нужно добавить в первую строку запроса после SUM(«Цена») так называемый псевдоним (подпись) с ключевым словом AS:
SELECT «Номер заказа», «Дата», SUM(«Цена») AS «Сумма»
…
Проверьте результат выполнения этого запроса. Псевдонимы можно задавать для всех значений, которые выводятся в запросе.
- Измените запрос так, чтобы заказы были отсортированы в порядке убывания суммы (используйте ключевые слова ORDER BY).
Ответ:
Вложенные запросы
- Построим запрос МинСумма, который выводит минимальную сумму заказа. Для этого будем использовать уже готовый запрос Итоги. Таким образом, источником данных для запроса МинСумма будет не таблица, а другой запрос. Отметим, что предварительно в запросе Итоги нужно отменить сортировку. Запрос получается очень простым
SELECT MIN(«Сумма») AS «Сумма» FROM «Итоги»
- Наконец, можно вывести информацию о заказе с минимальной суммой:
SELECT «Номер заказа», «Дата», «Сумма»
FROM «Итоги», «МинСумма»
WHERE «Итоги».»Сумма» = «МинСумма».»Сумма»
Обратите внимание, что этот запрос использует результаты выполнения двух ранее построенных запросов – Итоги и МинСумма. Запрос Итоги можно было и не составлять, а вместо этого использовать вложенный запрос (запрос в запросе):
SELECT «Номер заказа», «Дата», «Сумма»
FROM «Итоги»
WHERE «Сумма» =
(SELECT MIN(«Сумма«) FROM «Итоги«)
Заметим, что если в базе данных есть информация о нескольких заказах с такой же (минимальной) суммой, будет показана информация обо всех этих заказах.
- Измените запрос так, чтобы получить список всех заказов, сумма которых больше средней.
Ответ:
Вступление и DDL – Data Definition Language (язык описания данных)
Часть первая — habrahabr.ru/post/255361
DML – Data Manipulation Language (язык манипулирования данными)
В первой части мы уже немного затронули язык DML, применяя почти весь набор его команд, за исключением команды MERGE.
Рассказывать про DML я буду по своей последовательности выработанной на личном опыте. По ходу, так же постараюсь рассказать про «скользкие» места, на которые стоит акцентировать внимание, эти «скользкие» места, схожи во многих диалектах языка SQL.
Т.к. учебник посвящается широкому кругу читателей (не только программистам), то и объяснение, порой будет соответствующее, т.е. долгое и нудное. Это мое видение материала, которое в основном получено на практике в результате профессиональной деятельности.
Основная цель данного учебника, шаг за шагом, выработать полное понимание сути языка SQL и научить правильно применять его конструкции. Профессионалам в этой области, может тоже будет интересно пролистать данный материал, может и они смогут вынести для себя что-то новое, а может просто, будет полезно почитать в целях освежить память. Надеюсь, что всем будет интересно.
Т.к. DML в диалекте БД MS SQL очень сильно связан с синтаксисом конструкции SELECT, то я начну рассказывать о DML именно с нее. На мой взгляд конструкция SELECT является самой главной конструкцией языка DML, т.к. за счет нее или ее частей осуществляется выборка необходимых данных из БД.
Язык DML содержит следующие конструкции:
- SELECT – выборка данных
- INSERT – вставка новых данных
- UPDATE – обновление данных
- DELETE – удаление данных
- MERGE – слияние данных
В данной части, мы рассмотрим, только базовый синтаксис команды SELECT, который выглядит следующим образом:
SELECT [DISTINCT] список_столбцов или *
FROM источник
WHERE фильтр
ORDER BY выражение_сортировки
Тема оператора SELECT очень обширная, поэтому в данной части я и остановлюсь только на его базовых конструкциях. Я считаю, что, не зная хорошо базы, нельзя приступать к изучению более сложных конструкций, т.к. дальше все будет крутиться вокруг этой базовой конструкции (подзапросы, объединения и т.д.).
Также в рамках этой части, я еще расскажу о предложении TOP. Это предложение я намерено не указал в базовом синтаксисе, т.к. оно реализуется по-разному в разных диалектах языка SQL.
Если язык DDL больше статичен, т.е. при помощи него создаются жесткие структуры (таблицы, связи и т.п.), то язык DML носит динамический характер, здесь правильные результаты вы можете получить разными путями.
Обучение так же будет продолжаться в режиме Step by Step, т.е. при чтении нужно сразу же своими руками пытаться выполнить пример. После делаете анализ полученного результата и пытаетесь понять его интуитивно. Если что-то остается непонятным, например, значение какой-нибудь функции, то обращайтесь за помощью в интернет.
Примеры будут показываться на БД Test, которая была создана при помощи DDL+DML в первой части.
Для тех, кто не создавал БД в первой части (т.к. не всех может интересовать язык DDL), может воспользоваться следующим скриптом:
Скрипт создания БД Test
-- создание БД
CREATE DATABASE Test
GO
-- сделать БД Test текущей
USE Test
GO
-- создаем таблицы справочники
CREATE TABLE Positions(
ID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_Positions PRIMARY KEY,
Name nvarchar(30) NOT NULL
)
CREATE TABLE Departments(
ID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_Departments PRIMARY KEY,
Name nvarchar(30) NOT NULL
)
GO
-- заполняем таблицы справочники данными
SET IDENTITY_INSERT Positions ON
INSERT Positions(ID,Name)VALUES
(1,N'Бухгалтер'),
(2,N'Директор'),
(3,N'Программист'),
(4,N'Старший программист')
SET IDENTITY_INSERT Positions OFF
GO
SET IDENTITY_INSERT Departments ON
INSERT Departments(ID,Name)VALUES
(1,N'Администрация'),
(2,N'Бухгалтерия'),
(3,N'ИТ')
SET IDENTITY_INSERT Departments OFF
GO
-- создаем таблицу с сотрудниками
CREATE TABLE Employees(
ID int NOT NULL,
Name nvarchar(30),
Birthday date,
Email nvarchar(30),
PositionID int,
DepartmentID int,
HireDate date NOT NULL CONSTRAINT DF_Employees_HireDate DEFAULT SYSDATETIME(),
ManagerID int,
CONSTRAINT PK_Employees PRIMARY KEY (ID),
CONSTRAINT FK_Employees_DepartmentID FOREIGN KEY(DepartmentID) REFERENCES Departments(ID),
CONSTRAINT FK_Employees_PositionID FOREIGN KEY(PositionID) REFERENCES Positions(ID),
CONSTRAINT FK_Employees_ManagerID FOREIGN KEY (ManagerID) REFERENCES Employees(ID),
CONSTRAINT UQ_Employees_Email UNIQUE(Email),
CONSTRAINT CK_Employees_ID CHECK(ID BETWEEN 1000 AND 1999),
INDEX IDX_Employees_Name(Name)
)
GO
-- заполняем ее данными
INSERT Employees (ID,Name,Birthday,Email,PositionID,DepartmentID,ManagerID)VALUES
(1000,N'Иванов И.И.','19550219','i.ivanov@test.tt',2,1,NULL),
(1001,N'Петров П.П.','19831203','p.petrov@test.tt',3,3,1003),
(1002,N'Сидоров С.С.','19760607','s.sidorov@test.tt',1,2,1000),
(1003,N'Андреев А.А.','19820417','a.andreev@test.tt',4,3,1000)
Все, теперь мы готовы приступить к изучению языка DML.
SELECT – оператор выборки данных
Первым делом, для активного редактора запроса, сделаем текущей БД Test, выбрав ее в выпадающем списке или же командой «USE Test».
Начнем с самой элементарной формы SELECT:
SELECT *
FROM Employees
В данном запросе мы просим вернуть все столбцы (на это указывает «*») из таблицы Employees – можно прочесть это как «ВЫБЕРИ все_поля ИЗ таблицы_сотрудники». В случае наличия кластерного индекса, возвращенные данные, скорее всего будут отсортированы по нему, в данном случае по колонке ID (но это не суть важно, т.к. в большинстве случаев сортировку мы будем указывать в явном виде сами при помощи ORDER BY …):
ID | Name | Birthday | PositionID | DepartmentID | HireDate | ManagerID | |
---|---|---|---|---|---|---|---|
1000 | Иванов И.И. | 1955-02-19 | i.ivanov@test.tt | 2 | 1 | 2015-04-08 | NULL |
1001 | Петров П.П. | 1983-12-03 | p.petrov@test.tt | 3 | 3 | 2015-04-08 | 1003 |
1002 | Сидоров С.С. | 1976-06-07 | s.sidorov@test.tt | 1 | 2 | 2015-04-08 | 1000 |
1003 | Андреев А.А. | 1982-04-17 | a.andreev@test.tt | 4 | 3 | 2015-04-08 | 1000 |
Вообще стоит сказать, что в диалекте MS SQL самая простая форма запроса SELECT может не содержать блока FROM, в этом случае вы можете использовать ее, для получения каких-то значений:
SELECT
5550/100*15,
SYSDATETIME(), -- получение системной даты БД
SIN(0)+COS(0)
(No column name) | (No column name) | (No column name) |
---|---|---|
825 | 2015-04-11 12:12:36.0406743 | 1 |
Обратите внимание, что выражение (5550/100*15) дало результат 825, хотя если мы посчитаем на калькуляторе получится значение (832.5). Результат 825 получился по той причине, что в нашем выражении все числа целые, поэтому и результат целое число, т.е. (5550/100) дает нам 55, а не (55.5).
Запомните следующее, что в MS SQL работает следующая логика:
- Целое / Целое = Целое (т.е. в данном случае происходит целочисленное деление)
- Вещественное / Целое = Вещественное
- Целое / Вещественное = Вещественное
Т.е. результат преобразуется к большему типу, поэтому в 2-х последних случаях мы получаем вещественное число (рассуждайте как в математике – диапазон вещественных чисел больше диапазона целых, поэтому и результат преобразуется к нему):
SELECT
123/10, -- 12
123./10, -- 12.3
123/10. -- 12.3
Здесь (123.) = (123.0), просто в данном случае 0 можно отбросить и оставить только точку.
При других арифметических операциях действует та же самая логика, просто в случае деления этот нюанс более актуален.
Поэтому обращайте внимание на тип данных числовых столбцов. В том случае если он целый, а результат вам нужно получить вещественный, то используйте преобразование, либо просто ставьте точку после числа указанного в виде константы (123.).
Для преобразования полей можно использовать функцию CAST или CONVERT. Для примера воспользуемся полем ID, оно у нас типа int:
SELECT
ID,
ID/100, -- здесь произойдет целочисленное деление
CAST(ID AS float)/100, -- используем функцию CAST для преобразования в тип float
CONVERT(float,ID)/100, -- используем функцию CONVERT для преобразования в тип float
ID/100. -- используем преобразование за счет указания что знаменатель вещественное число
FROM Employees
ID | (No column name) | (No column name) | (No column name) | (No column name) |
---|---|---|---|---|
1000 | 10 | 10 | 10 | 10.000000 |
1001 | 10 | 10.01 | 10.01 | 10.010000 |
1002 | 10 | 10.02 | 10.02 | 10.020000 |
1003 | 10 | 10.03 | 10.03 | 10.030000 |
На заметку. В БД ORACLE синтаксис без блока FROM недопустим, там для этой цели используется системная таблица DUAL, которая содержит одну строку:
SELECT 5550/100*15, -- а в ORACLE результат будет равен 832.5 sysdate, sin(0)+cos(0) FROM DUAL
Примечание. Имя таблицы во многих РБД может предваряться именем схемы:
SELECT * FROM dbo.Employees -- dbo – имя схемы
Схема – это логическая единица БД, которая имеет свое наименование и позволяет сгруппировать внутри себя объекты БД такие как таблицы, представления и т.д.
Определение схемы в разных БД может отличатся, где-то схема непосредственно связанна с пользователем БД, т.е. в данном случае можно сказать, что схема и пользователь – это синонимы и все создаваемые в схеме объекты по сути являются объектами данного пользователя. В MS SQL схема – это независимая логическая единица, которая может быть создана сама по себе (см. CREATE SCHEMA).
По умолчанию в базе MS SQL создается одна схема с именем dbo (Database Owner) и все создаваемые объекты по умолчанию создаются именно в данной схеме. Соответственно, если мы в запросе указываем просто имя таблицы, то она будет искаться в схеме dbo текущей БД. Если мы хотим создать объект в конкретной схеме, мы должны будем так же предварить имя объекта именем схемы, например, «CREATE TABLE имя_схемы.имя_таблицы(…)».
В случае MS SQL имя схемы может еще предваряться именем БД, в которой находится данная схема:
SELECT * FROM Test.dbo.Employees -- имя_базы.имя_схемы.таблица
Такое уточнение бывает полезным, например, если:
- в одном запросе мы обращаемся к объектам расположенных в разных схемах или базах данных
- требуется сделать перенос данных из одной схемы или БД в другую
- находясь в одной БД, требуется запросить данные из другой БД
- и т.п.
Схема – очень удобное средство, которое полезно использовать при разработке архитектуры БД, а особенно крупных БД.
Так же не забываем, что в тексте запроса мы можем использовать как однострочные «— …», так и многострочные «/* … */» комментарии. Если запрос большой и сложный, то комментарии могут очень помочь, вам или кому-то другому, через некоторое время, вспомнить или разобраться в его структуре.
Если столбцов в таблице очень много, а особенно, если в таблице еще очень много строк, плюс к тому если мы делаем запросы к БД по сети, то предпочтительней будет выборка с непосредственным перечислением необходимых вам полей через запятую:
SELECT ID,Name
FROM Employees
Т.е. здесь мы говорим, что нам из таблицы нужно вернуть только поля ID и Name. Результат будет следующим (кстати оптимизатор здесь решил воспользоваться индексом, созданным по полю Name):
ID | Name |
---|---|
1003 | Андреев А.А. |
1000 | Иванов И.И. |
1001 | Петров П.П. |
1002 | Сидоров С.С. |
На заметку. Порой бывает полезным посмотреть на то как осуществляется выборка данных, например, чтобы выяснить какие индексы используются. Это можно сделать если нажать кнопку «Display Estimated Execution Plan – Показать расчетный план» или установить «Include Actual Execution Plan – Включить в результат актуальный план выполнения запроса» (в данном случае мы сможем увидеть уже реальный план, соответственно, только после выполнения запроса):
Анализ плана выполнения очень полезен при оптимизации запроса, он позволяет выяснить каких индексов не хватает или же какие индексы вообще не используются и их можно удалить.
Если вы только начали осваивать DML, то сейчас для вас это не так важно, просто возьмите на заметку и можете спокойно забыть об этом (может это вам никогда и не пригодится) – наша первоначальная цель изучить основы языка DML и научится правильно применять их, а оптимизация это уже отдельное искусство. Порой важнее, чтобы на руках просто был правильно написанный запрос, который возвращает правильные результат с предметной точки зрения, а его оптимизацией уже занимаются отдельные люди. Для начала вам нужно научиться просто правильно писать запросы, используя любые средства для достижения цели. Главная цель которую вы сейчас должны достичь – чтобы ваш запрос возвращал правильные результаты.
Задание псевдонимов для таблиц
При перечислении колонок их можно предварять именем таблицы, находящейся в блоке FROM:
SELECT Employees.ID,Employees.Name
FROM Employees
Но такой синтаксис обычно использовать неудобно, т.к. имя таблицы может быть длинным. Для этих целей обычно задаются и применяются более короткие имена – псевдонимы (alias):
SELECT emp.ID,emp.Name
FROM Employees AS emp
или
SELECT emp.ID,emp.Name
FROM Employees emp -- ключевое слово AS можно отпустить (я предпочитаю такой вариант)
Здесь emp – псевдоним для таблицы Employees, который можно будет использоваться в контексте данного оператора SELECT. Т.е. можно сказать, что в контексте этого оператора SELECT мы задаем таблице новое имя.
Конечно, в данном случае результаты запросов будут точно такими же как и для «SELECT ID,Name FROM Employees». Для чего это нужно будет понятно дальше (даже не в этой части), пока просто запоминаем, что имя колонки можно предварять (уточнять) либо непосредственно именем таблицы, либо при помощи псевдонима. Здесь можно использовать одно из двух, т.е. если вы задали псевдоним, то и пользоваться нужно будет им, а использовать имя таблицы уже нельзя.
На заметку. В ORACLE допустим только вариант задания псевдонима таблицы без ключевого слова AS.
DISTINCT – отброс строк дубликатов
Ключевое слово DISTINCT используется для того чтобы отбросить из результата запроса строки дубликаты. Грубо говоря представьте, что сначала выполняется запрос без опции DISTINCT, а затем из результата выбрасываются все дубликаты. Продемонстрируем это для большей наглядности на примере:
-- создадим для демонстрации временную таблицу
CREATE TABLE #Trash(
ID int NOT NULL PRIMARY KEY,
Col1 varchar(10),
Col2 varchar(10),
Col3 varchar(10)
)
-- наполним данную таблицу всяким мусором
INSERT #Trash(ID,Col1,Col2,Col3)VALUES
(1,'A','A','A'), (2,'A','B','C'), (3,'C','A','B'), (4,'A','A','B'),
(5,'B','B','B'), (6,'A','A','B'), (7,'A','A','A'), (8,'C','A','B'),
(9,'C','A','B'), (10,'A','A','B'), (11,'A',NULL,'B'), (12,'A',NULL,'B')
-- посмотрим что возвращает запрос без опции DISTINCT
SELECT Col1,Col2,Col3
FROM #Trash
-- посмотрим что возвращает запрос с опцией DISTINCT
SELECT DISTINCT Col1,Col2,Col3
FROM #Trash
-- удалим временную таблицу
DROP TABLE #Trash
Наглядно это будет выглядеть следующим образом (все дубликаты помечены одним цветом):
Теперь давайте рассмотрим где это можно применить, на более практичном примере – вернем из таблицы Employees только уникальные идентификаторы отделов (т.е. узнаем ID отделов в которых числятся сотрудники):
SELECT DISTINCT DepartmentID
FROM Employees
DepartmentID |
---|
1 |
2 |
3 |
Здесь мы получили три строки, т.к. 2 сотрудника у нас числятся в одном отделе (ИТ).
Теперь узнаем в каких отделах, какие должности фигурируют:
SELECT DISTINCT DepartmentID,PositionID
FROM Employees
DepartmentID | PositionID |
---|---|
1 | 2 |
2 | 1 |
3 | 3 |
3 | 4 |
Здесь мы получили 4 строчки, т.к. повторяющихся комбинаций (DepartmentID, PositionID) в нашей таблице нет.
Ненадолго вернемся к DDL
Так как данных для демонстрационных примеров начинает не хватать, а рассказать хочется более обширно и понятно, то давайте чуть расширим нашу таблицу Employess. К тому же немного вспомним DDL, как говорится «повторение – мать учения», и плюс снова немного забежим вперед и применим оператор UPDATE:
-- создаем новые колонки
ALTER TABLE Employees ADD
LastName nvarchar(30), -- фамилия
FirstName nvarchar(30), -- имя
MiddleName nvarchar(30), -- отчество
Salary float, -- и конечно же ЗП в каких-то УЕ
BonusPercent float -- процент для вычисления бонуса от оклада
GO
-- наполняем их данными (некоторые данные намерено пропущены)
UPDATE Employees
SET
LastName=N'Иванов',FirstName=N'Иван',MiddleName=N'Иванович',
Salary=5000,BonusPercent= 50
WHERE ID=1000 -- Иванов И.И.
UPDATE Employees
SET
LastName=N'Петров',FirstName=N'Петр',MiddleName=N'Петрович',
Salary=1500,BonusPercent= 15
WHERE ID=1001 -- Петров П.П.
UPDATE Employees
SET
LastName=N'Сидоров',FirstName=N'Сидор',MiddleName=NULL,
Salary=2500,BonusPercent=NULL
WHERE ID=1002 -- Сидоров С.С.
UPDATE Employees
SET
LastName=N'Андреев',FirstName=N'Андрей',MiddleName=NULL,
Salary=2000,BonusPercent= 30
WHERE ID=1003 -- Андреев А.А.
Убедимся, что данные обновились успешно:
SELECT *
FROM Employees
ID | Name | … | LastName | FirstName | MiddleName | Salary | BonusPercent |
---|---|---|---|---|---|---|---|
1000 | Иванов И.И. | Иванов | Иван | Иванович | 5000 | 50 | |
1001 | Петров П.П. | Петров | Петр | Петрович | 1500 | 15 | |
1002 | Сидоров С.С. | Сидоров | Сидор | NULL | 2500 | NULL | |
1003 | Андреев А.А. | Андреев | Андрей | NULL | 2000 | 30 |
Задание псевдонимов для столбцов запроса
Думаю, здесь будет проще показать, чем написать:
SELECT
-- даем имя вычисляемому столбцу
LastName+' '+FirstName+' '+MiddleName AS ФИО,
-- использование двойных кавычек, т.к. используется пробел
HireDate AS "Дата приема",
-- использование квадратных скобок, т.к. используется пробел
Birthday AS [Дата рождения],
-- слово AS не обязательно
Salary ZP
FROM Employees
ФИО | Дата приема | Дата рождения | ZP |
---|---|---|---|
Иванов Иван Иванович | 2015-04-08 | 1955-02-19 | 5000 |
Петров Петр Петрович | 2015-04-08 | 1983-12-03 | 1500 |
NULL | 2015-04-08 | 1976-06-07 | 2500 |
NULL | 2015-04-08 | 1982-04-17 | 2000 |
Как видим заданные нами псевдонимы столбцов, отразились в заголовке результирующей таблицы. Собственно, это и есть основное предназначение псевдонимов столбцов.
Обратите внимание, т.к. у последних 2-х сотрудников не указано отчество (NULL значение), то результат выражения «LastName+’ ‘+FirstName+’ ‘+MiddleName» так же вернул нам NULL.
Для соединения (сложения, конкатенации) строк в MS SQL используется символ «+».
Запомним, что все выражения в которых участвует NULL (например, деление на NULL, сложение с NULL) будут возвращать NULL.
На заметку.
В случае ORACLE для объединения строк используется оператор «||» и конкатенация будет выглядеть как «LastName||’ ‘||FirstName||’ ‘||MiddleName». Для ORACLE стоит отметить, что у него для строковых типов есть исключение, для них NULL и пустая строка » это одно и тоже, поэтому в ORACLE такое выражение вернет для последних 2-х сотрудников «Сидоров Сидор » и «Андреев Андрей ». На момент версии ORACLE 12c, насколько я знаю, опции которая изменяет такое поведение нет (если не прав, прошу поправить меня). Здесь мне сложно судить хорошо это или плохо, т.к. в одних случаях удобнее поведение NULL-строки как в MS SQL, а в других как в ORACLE.В ORACLE тоже допустимы все перечисленные выше псевдонимы столбцов, кроме […].
Для того чтобы не городить конструкцию с использованием функции ISNULL, в MS SQL мы можем применить функцию CONCAT. Рассмотрим и сравним 3 варианта:
SELECT
LastName+' '+FirstName+' '+MiddleName FullName1,
-- 2 варианта для замены NULL пустыми строками '' (получаем поведение как и в ORACLE)
ISNULL(LastName,'')+' '+ISNULL(FirstName,'')+' '+ISNULL(MiddleName,'') FullName2,
CONCAT(LastName,' ',FirstName,' ',MiddleName) FullName3
FROM Employees
FullName1 | FullName2 | FullName3 |
---|---|---|
Иванов Иван Иванович | Иванов Иван Иванович | Иванов Иван Иванович |
Петров Петр Петрович | Петров Петр Петрович | Петров Петр Петрович |
NULL | Сидоров Сидор | Сидоров Сидор |
NULL | Андреев Андрей | Андреев Андрей |
В MS SQL псевдонимы еще можно задавать при помощи знака равенства:
SELECT
'Дата приема'=HireDate, -- помимо "…" и […] можно использовать '…'
[Дата рождения]=Birthday,
ZP=Salary
FROM Employees
Использовать для задания псевдонима ключевое слово AS или же знак равенства, наверное, больше дело вкуса. Но при разборе чужих запросов, данные знания могут пригодиться.
Напоследок скажу, что для псевдонимов имена лучше задавать, используя только символы латиницы и цифры, избегая применения ‘…’, «…» и […], то есть использовать те же правила, что мы использовали при наименовании таблиц. Дальше, в примерах я буду использовать только такие наименования и никаких ‘…’, «…» и […].
Основные арифметические операторы SQL
Оператор | Действие |
---|---|
+ | Сложение (x+y) или унарный плюс (+x) |
— | Вычитание (x-y) или унарный минус (-x) |
* | Умножение (x*y) |
/ | Деление (x/y) |
% | Остаток от деления (x%y). Для примера 15%10 даст 5 |
Приоритет выполнения арифметических операторов такой же, как и в математике. Если необходимо, то порядок применения операторов можно изменить используя круглые скобки — (a+b)*(x/(y-z)).
И еще раз повторюсь, что любая операция с NULL дает NULL, например: 10+NULL, NULL*15/3, 100/NULL – все это даст в результате NULL. Т.е. говоря просто неопределенное значение не может дать определенный результат. Учитывайте это при составлении запроса и при необходимости делайте обработку NULL значений функциями ISNULL, COALESCE:
SELECT
ID,Name,
Salary/100*BonusPercent AS Result1, -- без обработки NULL значений
Salary/100*ISNULL(BonusPercent,0) AS Result2, -- используем функцию ISNULL
Salary/100*COALESCE(BonusPercent,0) AS Result3 -- используем функцию COALESCE
FROM Employees
ID | Name | Result1 | Result2 | Result3 |
---|---|---|---|---|
1000 | Иванов И.И. | 2500 | 2500 | 2500 |
1001 | Петров П.П. | 225 | 225 | 225 |
1002 | Сидоров С.С. | NULL | 0 | 0 |
1003 | Андреев А.А. | 600 | 600 | 600 |
1004 | Николаев Н.Н. | NULL | 0 | 0 |
1005 | Александров А.А. | NULL | 0 | 0 |
Немного расскажу о функции COALESCE:
COALESCE (expr1, expr2, ..., exprn) - Возвращает первое не NULL значение из списка значений.
Пример:
SELECT COALESCE(f1, f1*f2, f2*f3) val -- в данном случае вернется третье значение
FROM (SELECT null f1, 2 f2, 3 f3) q
В основном, я сосредоточусь на рассказе конструкций языка DML и по большей части не буду рассказывать о функциях, которые будут встречаться в примерах. Если вам непонятно, что делает та или иная функция поищите ее описание в интернет, можете даже поискать информацию сразу по группе функций, например, задав в поиске Google «MS SQL строковые функции», «MS SQL математические функции» или же «MS SQL функции обработки NULL». Информации по функциям очень много, и вы ее сможете без труда найти. Для примера, в библиотеке MSDN, можно узнать больше о функции COALESCE:
Вырезка из MSDN Сравнение COALESCE и CASE
Выражение COALESCE — синтаксический ярлык для выражения CASE. Это означает, что код COALESCE(expression1,…n) переписывается оптимизатором запросов как следующее выражение CASE:
CASE WHEN (expression1 IS NOT NULL) THEN expression1 WHEN (expression2 IS NOT NULL) THEN expression2 ... ELSE expressionN END
Для примера рассмотрим, как можно воспользоваться остатком от деления (%). Данный оператор очень полезен, когда требуется разбить записи на группы. Например, вытащим всех сотрудников, у которых четные табельные номера (ID), т.е. те ID, которые делятся на 2:
SELECT ID,Name
FROM Employees
WHERE ID%2=0 -- остаток от деления на 2 равен 0
ID | Name |
---|---|
1000 | Иванов И.И. |
1004 | Николаев Н.Н. |
1002 | Сидоров С.С. |
ORDER BY – сортировка результата запроса
Предложение ORDER BY используется для сортировки результата запроса.
SELECT
LastName,
FirstName,
Salary
FROM Employees
ORDER BY LastName,FirstName -- упорядочить результат по 2-м столбцам – по Фамилии, и после по Имени
LastName | FirstName | Salary |
---|---|---|
Андреев | Андрей | 2000 |
Иванов | Иван | 5000 |
Петров | Петр | 1500 |
Сидоров | Сидор | 2500 |
После имя поля в предложении ORDER BY можно задать опцию DESC, которая служит для сортировки этого поля в порядке убывания:
SELECT LastName,FirstName,Salary
FROM Employees
ORDER BY -- упорядочить в порядке
Salary DESC, -- 1. убывания Заработной Платы
LastName, -- 2. по Фамилии
FirstName -- 3. по Имени
LastName | FirstName | Salary |
---|---|---|
Иванов | Иван | 5000 |
Сидоров | Сидор | 2500 |
Андреев | Андрей | 2000 |
Петров | Петр | 1500 |
Для заметки. Для сортировки по возрастанию есть ключевое слово ASC, но так как сортировка по возрастанию применяется по умолчанию, то про эту опцию можно забыть (я не помню случая, чтобы я когда-то использовал эту опцию).
Стоит отметить, что в предложении ORDER BY можно использовать и поля, которые не перечислены в предложении SELECT (кроме случая, когда используется DISTINCT, об этом случае я расскажу ниже). Для примера забегу немного вперед используя опцию TOP и покажу, как например, можно отобрать 3-х сотрудников у которых самая высокая ЗП, с учетом что саму ЗП в целях конфиденциальности я показывать не должен:
SELECT TOP 3 -- вернуть только 3 первые записи из всего результата
ID,LastName,FirstName
FROM Employees
ORDER BY Salary DESC -- сортируем результат по убыванию Заработной Платы
ID | LastName | FirstName |
---|---|---|
1000 | Иванов | Иван |
1002 | Сидоров | Сидор |
Конечно здесь есть случай, что у нескольких сотрудников может быть одинаковая ЗП и тут сложно сказать каких именно трех сотрудников вернет данный запрос, это уже нужно решать с постановщиком задачи. Допустим, после обсуждения с постановщиком данной задачи, вы согласовали и решили использовать следующий вариант – сделать дополнительную сортировку по полю даты рождения (т.е. молодым у нас дорога), а если и дата рождения у нескольких сотрудников может совпасть (ведь такое тоже не исключено), то можно сделать третью сортировку по убыванию значений ID (в последнюю очередь под выборку попадут те, у кого ID окажется максимальным – например, те кто был принят последним, допустим табельные номера у нас выдаются последовательно):
SELECT TOP 3 -- вернуть только 3 первые записи из всего результата
ID,LastName,FirstName
FROM Employees
ORDER BY
Salary DESC, -- 1. сортируем результат по убыванию Заработной Платы
Birthday, -- 2. потом по Дате рождения
ID DESC -- 3. и для полной однозначности результата добавляем сортировку по ID
Т.е. вы должны стараться чтобы результат запроса был предсказуемым, чтобы вы могли в случае разбора полетов объяснить почему в «черный список» попали именно эти люди, т.е. все было выбрано честно, по утверждённым правилам.
Сортировать можно так же используя разные выражения в предложении ORDER BY:
SELECT LastName,FirstName
FROM Employees
ORDER BY CONCAT(LastName,' ',FirstName) -- используем выражение
Так же в ORDER BY можно использовать псевдонимы заданные для колонок:
SELECT CONCAT(LastName,' ',FirstName) fi
FROM Employees
ORDER BY fi -- используем псевдоним
Стоит отметить что в случае использования предложения DISTINCT, в предложении ORDER BY могут использоваться только колонки, перечисленные в блоке SELECT. Т.е. после применения операции DISTINCT мы получаем новый набор данных, с новым набором колонок. По этой причине, следующий пример не отработает:
SELECT DISTINCT
LastName,FirstName,Salary
FROM Employees
ORDER BY ID -- ID отсутствует в итоговом наборе, который мы получили при помощи DISTINCT
Т.е. предложение ORDER BY применяется уже к итоговому набору, перед выдачей результата пользователю.
Примечание 1. Так же в предложении ORDER BY можно использовать номера столбцов, перечисленных в SELECT:
SELECT LastName,FirstName,Salary FROM Employees ORDER BY -- упорядочить в порядке 3 DESC, -- 1. убывания Заработной Платы 1, -- 2. по Фамилии 2 -- 3. по Имени
Для начинающих выглядит удобно и заманчиво, но лучше забыть и никогда не использовать такой вариант сортировки.
Если в данном случае (когда поля явно перечислены), такой вариант еще допустим, то для случая с использованием «*» такой вариант лучше никогда не применять. Почему – потому что, если кто-то, например, поменяет в таблице порядок столбцов, или удалит столбцы (и это нормальная ситуация), ваш запрос может так же работать, но уже неправильно, т.к. сортировка уже может идти по другим столбцам, и это коварно тем что данная ошибка может обнаружиться очень нескоро.
В случае, если бы столбы были явно перечислены, то в вышеуказанной ситуации, запрос либо бы продолжал работать, но также правильно (т.к. все явно определено), либо бы он просто выдал ошибку, что данного столбца не существует.
Так что можете смело забыть, о сортировке по номерам столбцов.
Примечание 2.
В MS SQL при сортировке по возрастанию NULL значения будут отображаться первыми.SELECT BonusPercent FROM Employees ORDER BY BonusPercent
Соответственно при использовании DESC они будут в конце
SELECT BonusPercent FROM Employees ORDER BY BonusPercent DESC
Если необходимо поменять логику сортировки NULL значений, то используйте выражения, например:
SELECT BonusPercent FROM Employees ORDER BY ISNULL(BonusPercent,100)
В ORACLE для этой цели предусмотрены 2 опции NULLS FIRST и NULLS LAST (применяется по умолчанию). Например:
SELECT BonusPercent FROM Employees ORDER BY BonusPercent DESC NULLS LAST
Обращайте на это внимание при переходе на ту или иную БД.
TOP – возврат указанного числа записей
Вырезка из MSDN. TOP – ограничивает число строк, возвращаемых в результирующем наборе запроса до заданного числа или процентного значения. Если предложение TOP используется совместно с предложением ORDER BY, то результирующий набор ограничен первыми N строками отсортированного результата. В противном случае возвращаются первые N строк в неопределенном порядке.
Обычно данное выражение используется с предложением ORDER BY и мы уже смотрели примеры, когда нужно было вернуть N-первых строк из результирующего набора.
Без ORDER BY обычно данное предложение применяется, когда нужно просто посмотреть на неизвестную нам таблицу, в которой может быть очень много записей, в этом случае мы можем, для примера, попросить вернуть нам только первые 10 строк, но для наглядности мы скажем только 2:
SELECT TOP 2
*
FROM Employees
Так же можно указать слово PERCENT, для того чтобы вернулось соответствуй процент строк из результирующего набора:
SELECT TOP 25 PERCENT
*
FROM Employees
На моей практике чаше применяется именно выборка по количеству строк.
Так же с TOP можно использовать опцию WITH TIES, которая поможет вернуть все строки в случае неоднозначной сортировки, т.е. это предложение вернет все строки, которые равны по составу строкам, которые попадают в выборку TOP N, в итоге строк может быть выбрано больше чем N. Давайте для демонстрации добавим еще одного «Программиста» с окладом 1500:
INSERT Employees(ID,Name,Email,PositionID,DepartmentID,ManagerID,Salary)
VALUES(1004,N'Николаев Н.Н.','n.nikolayev@test.tt',3,3,1003,1500)
и введем еще одного сотрудника без указания должности и отдела с окладом 2000:
INSERT Employees(ID,Name,Email,PositionID,DepartmentID,ManagerID,Salary)
VALUES(1005,N'Александров А.А.','a.alexandrov@test.tt',NULL,NULL,1000,2000)
Теперь давайте выберем при помощи опции WITH TIES всех сотрудников, у которых оклад совпадает с окладами 3-х сотрудников, с самым маленьким окладом (надеюсь дальше будет понятно, к чему я клоню):
SELECT TOP 3 WITH TIES
ID,Name,Salary
FROM Employees
ORDER BY Salary
Здесь хоть и указано TOP 3, но запрос вернул 4 записи, т.к. значение Salary которое вернуло TOP 3 (1500 и 2000) оказалось у 4-х сотрудников. Наглядно это работает примерно следующим образом:
На заметку.
В разных БД TOP реализуется разными способами, в MySQL для этого есть предложение LIMIT, в котором дополнительно можно задать начальное смещение.В ORACLE 12c, тоже ввели свой аналог совмещающий функциональность TOP и LIMIT – ищите по словам «ORACLE OFFSET FETCH». До версии 12c для этой цели обычно использовался псевдостолбец ROWNUM.
А что же будет если применить одновременно предложения DISTINCT и TOP? На такие вопросы легко ответить, проводя эксперименты. В общем, не бойтесь и не ленитесь экспериментировать, т.к. большая часть познается именно на практике. Порядок слов в операторе SELECT следующий, первым идет DISTINCT, а после него идет TOP, т.е. если рассуждать логически и читать слева-направо, то первым применится отброс дубликатов, а потом уже по этому набору будет сделан TOP. Что-ж проверим и убедимся, что так и есть:
SELECT DISTINCT TOP 2
Salary
FROM Employees
ORDER BY Salary
Salary |
---|
1500 |
2000 |
Т.е. в результате мы получили 2 самые маленькие зарплаты из всех. Конечно может быть случай что ЗП для каких-то сотрудников может быть не указанной (NULL), т.к. схема нам это позволяет. Поэтому в зависимости от задачи принимаем решение либо обработать NULL значения в предложении ORDER BY, либо просто отбросить все записи, у которых Salary равна NULL, а для этого переходим к изучению предложения WHERE.
WHERE – условие выборки строк
Данное предложение служит для фильтрации записей по заданному условию. Например, выберем всех сотрудников работающих в «ИТ» отделе (его ID=3):
SELECT ID,LastName,FirstName,Salary
FROM Employees
WHERE DepartmentID=3 -- ИТ
ORDER BY LastName,FirstName
ID | LastName | FirstName | Salary |
---|---|---|---|
1004 | NULL | NULL | 1500 |
1003 | Андреев | Андрей | 2000 |
1001 | Петров | Петр | 1500 |
Предложение WHERE пишется до команды ORDER BY.
Порядок применения команд к исходному набору Employees следующий:
- WHERE – если указано, то первым делом из всего набора Employees идет отбор только удовлетворяющих условию записей
- DISTINCT – если указано, то отбрасываются все дубликаты
- ORDER BY – если указано, то делается сортировка результата
- TOP – если указано, то из отсортированного результата возвращается только указанное число записей
Рассмотрим для наглядности пример:
SELECT DISTINCT TOP 1
Salary
FROM Employees
WHERE DepartmentID=3
ORDER BY Salary
Наглядно это будет выглядеть следующим образом:
Стоит отметить, что проверка на NULL делается не знаком равенства, а при помощи операторов IS NULL и IS NOT NULL. Просто запомните, что на NULL при помощи оператора «=» (знак равенства) сравнивать нельзя, т.к. результат выражения будет так же равен NULL.
Например, выберем всех сотрудников, у которых не указан отдел (т.е. DepartmentID IS NULL):
SELECT ID,Name
FROM Employees
WHERE DepartmentID IS NULL
ID | Name |
---|---|
1005 | Александров А.А. |
Теперь для примера посчитаем бонус для всех сотрудников у которых указано значение BonusPercent (т.е. BonusPercent IS NOT NULL):
SELECT ID,Name,Salary/100*BonusPercent AS Bonus
FROM Employees
WHERE BonusPercent IS NOT NULL
Да, кстати, если подумать, то значение BonusPercent может равняться нулю (0), а так же значение может быть внесено со знаком минус, ведь мы не накладывали на данное поле никаких ограничений.
Хорошо, рассказав о проблеме, нам пока сказали считать, что если (BonusPercent<=0 или BonusPercent IS NULL), то это означает что у сотрудника так же нет бонуса. Для начала, как нам сказали, так и сделаем, реализуем это при помощи логического оператора OR и NOT:
SELECT ID,Name,Salary/100*BonusPercent AS Bonus
FROM Employees
WHERE NOT(BonusPercent<=0 OR BonusPercent IS NULL)
Т.е. здесь мы начали изучать булевы операторы. Выражение в скобках «(BonusPercent<=0 OR BonusPercent IS NULL)» проверяет на то что у сотрудника нет бонуса, а NOT инвертирует это значение, т.е. говорит «верни всех сотрудников которые не сотрудники у которых нет бонуса».
Так же данное выражение можно переписать и сразу сказав сразу «верни всех сотрудников, у которых есть бонус» выразив это выражением (BonusPercent>0 и BonusPercent IS NOT NULL):
SELECT ID,Name,Salary/100*BonusPercent AS Bonus
FROM Employees
WHERE BonusPercent>0 AND BonusPercent IS NOT NULL
Также в блоке WHERE можно делать проверку разного рода выражений с применением арифметических операторов и функций. Например, аналогичную проверку можно сделать, использовав выражение с функцией ISNULL:
SELECT ID,Name,Salary/100*BonusPercent AS Bonus
FROM Employees
WHERE ISNULL(BonusPercent,0)>0
Булевы операторы и простые операторы сравнения
Да, без математики здесь не обойтись, поэтому сделаем небольшой экскурс по булевым и простым операторам сравнения.
Булевых операторов в языке SQL всего 3 – AND, OR и NOT:
AND | логическое И. Ставится между двумя условиями (условие1 AND условие2). Чтобы выражение вернуло True, нужно, чтобы истинными были оба условия |
---|---|
OR | логическое ИЛИ. Ставится между двумя условиями (условие1 OR условие2). Чтобы выражение вернуло True, достаточно, чтобы истинным было только одно условие |
NOT | инвертирует условие/логическое_выражение. Накладывается на другое выражение (NOT логическое_выражение) и возвращает True, если логическое_выражение = False и возвращает False, если логическое_выражение = True |
Для каждого булева оператора можно привести таблицы истинности где дополнительно показано какой будет результат, когда условия могут быть равны NULL:
Есть следующие простые операторы сравнения, которые используются для формирования условий:
Условие | Значение |
---|---|
= | Равно |
< | Меньше |
> | Больше |
<= | Меньше или равно |
>= | Больше или равно |
<> != |
Не равно |
Плюс имеются 2 оператора для проверки значения/выражения на NULL:
IS NULL | Проверка на равенство NULL |
---|---|
IS NOT NULL | Проверка на неравенство NULL |
Приоритет: 1) Все операторы сравнения; 2) NOT; 3) AND; 4) OR.
При построении сложных логических выражений используются круглые скобки:
((условие1 AND условие2) OR NOT(условие3 AND условие4 AND условие5)) OR (…)
Так же при помощи использования круглых скобок, можно изменить стандартную последовательность вычислений.
Здесь я постарался дать представление о булевой алгебре в достаточном для работы объеме. Как видите, чтобы писать условия посложнее без логики уже не обойтись, но ее здесь немного (AND, OR и NOT) и придумывали ее люди, так что все достаточно логично.
Идем к завершению второй части
Как видите даже про базовый синтаксис оператора SELECT можно говорить очень долго, но, чтобы остаться в рамках статьи, напоследок я покажу дополнительные логических операторы – BETWEEN, IN и LIKE.
BETWEEN – проверка на вхождение в диапазон
Этот оператор имеет следующий вид:
проверяемое_значение [NOT] BETWEEN начальное_ значение AND конечное_ значение
В роли значений могут выступать выражения.
Разберем на примере:
SELECT ID,Name,Salary
FROM Employees
WHERE Salary BETWEEN 2000 AND 3000 -- у кого ЗП в диапазоне 2000-3000
ID | Name | Salary |
---|---|---|
1002 | Сидоров С.С. | 2500 |
1003 | Андреев А.А. | 2000 |
1005 | Александров А.А. | 2000 |
Собственно, BETWEEN это упрощенная запись вида:
SELECT ID,Name,Salary
FROM Employees
WHERE Salary>=2000 AND Salary<=3000 -- все у кого ЗП в диапозоне 2000-3000
Перед словом BETWEEN может использоваться слово NOT, которое будет осуществлять проверку значения на не вхождение в указанный диапазон:
SELECT ID,Name,Salary
FROM Employees
WHERE Salary NOT BETWEEN 2000 AND 3000 -- аналогично выражению NOT(Salary>=2000 AND Salary<=3000)
Соответственно, в случае использования BETWEEN, IN, LIKE вы можете так же объединять их с другими условиями при помощи AND и OR:
SELECT ID,Name,Salary
FROM Employees
WHERE Salary BETWEEN 2000 AND 3000 -- у кого ЗП в диапазоне 2000-3000
AND DepartmentID=3 -- учитывать сотрудников только отдела 3
IN – проверка на вхождение в перечень значений
Этот оператор имеет следующий вид:
проверяемое_значение [NOT] IN (значение1, значение2, …)
Думаю, проще показать на примере:
SELECT ID,Name,Salary
FROM Employees
WHERE PositionID IN(3,4) -- у кого должность равна 3 или 4
ID | Name | Salary |
---|---|---|
1001 | Петров П.П. | 1500 |
1003 | Андреев А.А. | 2000 |
1004 | Николаев Н.Н. | 1500 |
Т.е. по сути это аналогично следующему выражению:
SELECT ID,Name,Salary
FROM Employees
WHERE PositionID=3 OR PositionID=4 -- у кого должность равна 3 или 4
В случае NOT это будет аналогично (получим всех кроме тех, кто из отдела 3 и 4):
SELECT ID,Name,Salary
FROM Employees
WHERE PositionID NOT IN(3,4) -- аналогично выражению NOT(PositionID=3 OR PositionID=4)
Так же запрос с NOT IN можно выразить и через AND:
SELECT ID,Name,Salary
FROM Employees
WHERE PositionID<>3 AND PositionID<>4 -- равносильно PositionID NOT IN(3,4)
Учтите, что искать NULL значения при помощи конструкции IN не получится, т.к. проверка NULL=NULL вернет так же NULL, а не True:
SELECT ID,Name,DepartmentID
FROM Employees
WHERE DepartmentID IN(1,2,NULL) -- NULL записи не войдут в результат
В этом случае разбивайте проверку на несколько условий:
SELECT ID,Name,DepartmentID
FROM Employees
WHERE DepartmentID IN(1,2) -- 1 или 2
OR DepartmentID IS NULL -- или NULL
Или же можно написать что-то вроде:
SELECT ID,Name,DepartmentID
FROM Employees
WHERE ISNULL(DepartmentID,-1) IN(1,2,-1) -- если вы уверены, что в нет и не будет департамента с ID=-1
Думаю, первый вариант, в данном случае будет более правильным и надежным. Ну ладно, это всего лишь пример, для демонстрации того какие еще конструкции можно строить.
Так же стоит упомянуть еще более коварную ошибку, связанную с NULL, которую можно допустить при использовании конструкции NOT IN. Для примера, давайте попробуем выбрать всех сотрудников, кроме тех, у которых отдел равен 1 или у которых отдел вообще не указан, т.е. равен NULL. В качестве решения напрашивается вариант:
SELECT ID,Name,DepartmentID
FROM Employees
WHERE DepartmentID NOT IN(1,NULL)
Но выполнив запрос, мы не получим ни одной строки, хотя мы ожидали увидеть следующее:
ID | Name | DepartmentID |
---|---|---|
1001 | Петров П.П. | 3 |
1002 | Сидоров С.С. | 2 |
1003 | Андреев А.А. | 3 |
1004 | Николаев Н.Н. | 3 |
Опять же шутку здесь сыграло NULL указанное в списке значений.
Разберем почему в данном случае возникла логическая ошибка. Разложим запрос при помощи AND:
SELECT ID,Name,DepartmentID
FROM Employees
WHERE DepartmentID<>1
AND DepartmentID<>NULL -- проблема из-за этой проверки на NULL - это условие всегда вернет NULL
Правое условие (DepartmentID<>NULL) нам всегда здесь даст неопределенность, т.е. NULL. Теперь вспомним таблицу истинности для оператора AND, где (TRUE AND NULL) дает NULL. Т.е. при выполнении левого условия (DepartmentID<>1) из-за неопределенного правого условия в результате мы получим неопределенное значение всего выражения (DepartmentID<>1 AND DepartmentID<>NULL), поэтому строка не войдет в результат.
Переписать условие правильно можно следующим образом:
SELECT ID,Name,DepartmentID
FROM Employees
WHERE DepartmentID NOT IN(1) -- или в данном случае просто DepartmentID<>1
AND DepartmentID IS NOT NULL -- и отдельно проверяем на NOT NULL
IN еще можно использовать с подзапросами, но к такой форме мы вернемся, уже в последующих частях данного учебника.
LIKE – проверка строки по шаблону
Про данный оператор я расскажу только в самом простом виде, который является стандартом и поддерживается большинством диалектов языка SQL. Даже в таком виде при помощи него можно решить много задач, которые требуют выполнить проверку по содержимому строки.
Этот оператор имеет следующий вид:
проверяемая_строка [NOT] LIKE строка_шаблон [ESCAPE отменяющий_символ]
В «строке_шаблон» могут применятся следующие специальные символы:
- Знак подчеркивания «_» — говорит, что на его месте может стоять любой единичный символ
- Знак процента «%» — говорит, что на его месте может стоять сколько угодно символов, в том числе и ни одного
Рассмотрим примеры с символом «%» (на практике, кстати он чаще применяется):
SELECT ID,Name
FROM Employees
WHERE Name LIKE 'Пет%' -- у кого имя начинается с букв "Пет"
SELECT ID,LastName
FROM Employees
WHERE LastName LIKE '%ов' -- у кого фамилия оканчивается на "ов"
SELECT ID,LastName
FROM Employees
WHERE LastName LIKE '%ре%' -- у кого фамилия содержит сочетание "ре"
Рассмотрим примеры с символом «_»:
SELECT ID,LastName
FROM Employees
WHERE LastName LIKE '_етров' -- у кого фамилия состоит из любого первого символа и последующих букв "етров"
SELECT ID,LastName
FROM Employees
WHERE LastName LIKE '____ов' -- у кого фамилия состоит из четырех любых символов и последующих букв "ов"
При помощи ESCAPE можно задать отменяющий символ, который отменяет проверяющее действие специальных символов «_» и «%». Данное предложение используется, когда в строке нужно непосредственно проверить наличие знака процента или знака подчеркивания.
Для демонстрации ESCAPE давайте занесем в одну запись мусор:
UPDATE Employees
SET
FirstName='Это_мусор, содержащий %'
WHERE ID=1005
И посмотрим, что вернут следующие запросы:
SELECT *
FROM Employees
WHERE FirstName LIKE '%!%%' ESCAPE '!' -- строка содержит знак "%"
SELECT *
FROM Employees
WHERE FirstName LIKE '%!_%' ESCAPE '!' -- строка содержит знак "_"
В случае, если требуется проверить строку на полное совпадение, то вместо LIKE лучше использовать просто знак «=»:
SELECT *
FROM Employees
WHERE FirstName='Петр'
На заметку.
В MS SQL в шаблоне оператора LIKE так же можно задать поиск по регулярным выражениям, почитайте о нем в интернете, в том случае, если вам станет недостаточно стандартных возможностей данного оператора.В ORACLE для поиска по регулярным выражениям применяется функция REGEXP_LIKE.
Немного о строках
В случае проверки строки на наличие Unicode символов, нужно будет ставить перед кавычками символ N, т.е. N’…’. Но так как у нас в таблице все символьные поля в формате Unicode (тип nvarchar), то для этих полей можно всегда использовать такой формат. Пример:
SELECT ID,Name
FROM Employees
WHERE Name LIKE N'Пет%'
SELECT ID,LastName
FROM Employees
WHERE LastName=N'Петров'
Если делать правильно, при сравнении с полем типа varchar (ASCII) нужно стараться использовать проверки с использованием ‘…’, а при сравнении поля с типом nvarchar (Unicode) нужно стараться использовать проверки с использованием N’…’. Это делается для того, чтобы избежать в процессе выполнения запроса неявных преобразований типов. То же самое правило используем при вставке (INSERT) значений в поле или их обновлении (UPDATE).
При сравнении строк стоит учесть момент, что в зависимости от настройки БД (collation), сравнение строк может быть, как регистро-независимым (когда ‘Петров’=’ПЕТРОВ’), так и регистро-зависимым (когда ‘Петров'<>’ПЕТРОВ’).
В случае регистро-зависимой настройки, если требуется сделать поиск без учета регистра, то можно, например, сделать предварительное преобразование правого и левого выражения в один регистр – верхний или нижний:
SELECT ID,Name
FROM Employees
WHERE UPPER(Name) LIKE UPPER(N'Пет%') -- или LOWER(Name) LIKE LOWER(N'Пет%')
SELECT ID,LastName
FROM Employees
WHERE UPPER(LastName)=UPPER(N'Петров') -- или LOWER(LastName)=LOWER(N'Петров')
Немного о датах
При проверке на дату, вы можете использовать, как и со строками одинарные кавычки ‘…’.
Вне зависимости от региональных настроек в MS SQL можно использовать следующий синтаксис дат ‘YYYYMMDD’ (год, месяц, день слитно без пробелов). Такой формат даты MS SQL поймет всегда:
SELECT ID,Name,Birthday
FROM Employees
WHERE Birthday BETWEEN '19800101' AND '19891231' -- сотрудники 80-х годов
ORDER BY Birthday
В некоторых случаях, дату удобнее задавать при помощи функции DATEFROMPARTS:
SELECT ID,Name,Birthday
FROM Employees
WHERE Birthday BETWEEN DATEFROMPARTS(1980,1,1) AND DATEFROMPARTS(1989,12,31)
ORDER BY Birthday
Так же есть аналогичная функция DATETIMEFROMPARTS, которая служит для задания Даты и Времени (для типа datetime).
Еще вы можете использовать функцию CONVERT, если требуется преобразовать строку в значение типа date или datetime:
SELECT
CONVERT(date,'12.03.2015',104),
CONVERT(datetime,'2014-11-30 17:20:15',120)
Значения 104 и 120, указывают какой формат даты используется в строке. Описание всех допустимых форматов вы можете найти в библиотеке MSDN задав в поиске «MS SQL CONVERT».
Функций для работы с датами в MS SQL очень много, ищите «ms sql функции для работы с датами».
Примечание. Во всех диалектах языка SQL свой набор функций по работе с датами и применяется свой подход по работе с ними.
Немного о числах и их преобразованиях
Информация этого раздела наверно больше будет полезна ИТ-специалистам. Если вы таковым не являетесь, а ваша цель просто научится писать запросы для получения из БД необходимой вам информации, то такие тонкости вам возможно и не понадобятся, но в любом случае можете бегло пройтись по тексту и взять что-то на заметку, т.к. если вы взялись за изучение SQL, то вы уже приобщаетесь к ИТ.
В отличие от функции преобразования CAST, в функции CONVERT можно задать третий параметр, который отвечает за стиль преобразования (формат). Для разных типов данных может использоваться свой набор стилей, которые могут повлиять на возвращаемый результат. Использование стилей мы уже затрагивали при рассмотрении преобразования строки функцией CONVERT в типы date и datetime.
Подробней про функции CAST, CONVERT и стили можно почитать в MSDN – «Функции CAST и CONVERT (Transact-SQL)»: msdn.microsoft.com/ru-ru/library/ms187928.aspx
Для упрощения примеров здесь будут использованы инструкции языка Transact-SQL – DECLARE и SET.
Конечно, в случае преобразования целого числа в вещественное (которое я привел вначале данного урока, в целях демонстрации разницы между целочисленным и вещественным делением), знание нюансов преобразования не так критично, т.к. там мы делали преобразование целого числа в вещественное (диапазон которого намного больше диапазона целых):
DECLARE @min_int int SET @min_int=-2147483648
DECLARE @max_int int SET @max_int=2147483647
SELECT
-- (-2147483648)
@min_int,CAST(@min_int AS float),CONVERT(float,@min_int),
-- 2147483647
@max_int,CAST(@max_int AS float),CONVERT(float,@max_int),
-- numeric(16,6)
@min_int/1., -- (-2147483648.000000)
@max_int/1. -- 2147483647.000000
Возможно не стоило указывать способ неявного преобразования, получаемого делением на (1.), т.к. желательно стараться делать явные преобразования, для большего контроля типа получаемого результата. Хотя, в случае, если мы хотим получить результат типа numeric, с указанным количеством цифр после запятой, то мы можем в MS SQL применить трюк с умножением целого значения на (1., 1.0, 1.00 и т.д):
DECLARE @int int SET @int=123
SELECT
@int*1., -- numeric(12, 0) - 0 знаков после запятой
@int*1.0, -- numeric(13, 1) - 1 знак
@int*1.00, -- numeric(14, 2) - 2 знака
-- хотя порой лучше сделать явное преобразование
CAST(@int AS numeric(20, 0)), -- 123
CAST(@int AS numeric(20, 1)), -- 123.0
CAST(@int AS numeric(20, 2)) -- 123.00
В некоторых случаях детали преобразования могут быть действительно важны, т.к. они влияют на правильность полученного результата, например, в случае, когда делается преобразование числового значения в строку (varchar). Рассмотрим примеры по преобразованию значений типа money и float в varchar:
-- поведение при преобразовании money в varchar
DECLARE @money money
SET @money = 1025.123456789 -- произойдет неявное преобразование в 1025.1235, т.к. тип money хранит только 4 цифры после запятой
SELECT
@money, -- 1025.1235
-- по умолчанию CAST и CONVERT ведут себя одинаково (т.е. грубо говоря применяется стиль 0)
CAST(@money as varchar(20)), -- 1025.12
CONVERT(varchar(20), @money), -- 1025.12
CONVERT(varchar(20), @money, 0), -- 1025.12 (стиль 0 - без разделителя тысячных и 2 цифры после запятой (формат по умолчанию))
CONVERT(varchar(20), @money, 1), -- 1,025.12 (стиль 1 - используется разделитель тысячных и 2 цифры после запятой)
CONVERT(varchar(20), @money, 2) -- 1025.1235 (стиль 2 - без разделителя и 4 цифры после запятой)
-- поведение при преобразовании float в varchar
DECLARE @float1 float SET @float1 = 1025.123456789
DECLARE @float2 float SET @float2 = 1231025.123456789
SELECT
@float1, -- 1025.123456789
@float2, -- 1231025.12345679
-- по умолчанию CAST и CONVERT ведут себя одинаково (т.е. грубо говоря применяется стиль 0)
-- стиль 0 - Не более 6 разрядов. По необходимости используется экспоненциальное представление чисел
-- при преобразовании в varchar здесь творятся действительно страшные вещи
CAST(@float1 as varchar(20)), -- 1025.12
CONVERT(varchar(20), @float1), -- 1025.12
CONVERT(varchar(20), @float1, 0), -- 1025.12
CAST(@float2 as varchar(20)), -- 1.23103e+006
CONVERT(varchar(20), @float2), -- 1.23103e+006
CONVERT(varchar(20), @float2, 0), -- 1.23103e+006
-- стиль 1 - Всегда 8 разрядов. Всегда используется экспоненциальное представление чисел.
-- этот стиль для float тоже не очень точен
CONVERT(varchar(20), @float1, 1), -- 1.0251235e+003
CONVERT(varchar(20), @float2, 1), -- 1.2310251e+006
-- стиль 2 - Всегда 16 разрядов. Всегда используется экспоненциальное представление чисел.
-- здесь с точностью уже получше
CONVERT(varchar(30), @float1, 2), -- 1.025123456789000e+003 - OK
CONVERT(varchar(30), @float2, 2) -- 1.231025123456789e+006 - OK
Как видно из примера, плавающие типы float, real в некоторых случаях действительно могут создать большую погрешность, особенно при перегонке в строку и обратно (такое может быть при разного рода интеграциях, когда данные, например, передаются в текстовых файлах из одной системы в другую).
Если нужно явно контролировать точность до определенного знака, более 4-х, то для хранения данных, порой лучше использовать тип decimal/numeric. Если хватает 4-х знаков, то можно использовать и тип money – он примерно соотвествует numeric(20,4).
-- decimal и numeric
DECLARE @money money SET @money = 1025.123456789 -- 1025.1235
DECLARE @float1 float SET @float1 = 1025.123456789
DECLARE @float2 float SET @float2 = 1231025.123456789
DECLARE @numeric numeric(28,9) SET @numeric = 1025.123456789
SELECT
CAST(@numeric as varchar(20)), -- 1025.12345679
CONVERT(varchar(20), @numeric), -- 1025.12345679
CAST(@money as numeric(28,9)), -- 1025.123500000
CAST(@float1 as numeric(28,9)), -- 1025.123456789
CAST(@float2 as numeric(28,9)) -- 1231025.123456789
Примечание.
С версии MS SQL 2008, можно использовать вместо конструкции:DECLARE @money money SET @money = 1025.123456789
Более короткий синтаксис инициализации переменных:
DECLARE @money money = 1025.123456789
Заключение второй части
В этой части, я постарался вспомнить и отразить наиболее важные моменты, касающиеся базового синтаксиса. Базовая конструкция – это костяк, без которого нельзя приступать к изучению более сложных конструкций языка SQL.
Надеюсь, данный материал поможет людям, делающим первые шаги в изучении языка SQL.
Удачи в изучении и применении на практике данного языка.
Часть третья — habrahabr.ru/post/255825
Improve Article
Save Article
Improve Article
Save Article
Aliases are the temporary names given to table or column for the purpose of a particular SQL query. It is used when name of column or table is used other than their original names, but the modified name is only temporary.
- Aliases are created to make table or column names more readable.
- The renaming is just a temporary change and table name does not change in the original database.
- Aliases are useful when table or column names are big or not very readable.
- These are preferred when there are more than one table involved in a query.
Basic Syntax:
- For column alias:
SELECT column as alias_name FROM table_name; column: fields in the table alias_name: temporary alias name to be used in replacement of original column name table_name: name of table
- For table alias:
SELECT column FROM table_name as alias_name; column: fields in the table table_name: name of table alias_name: temporary alias name to be used in replacement of original table name
Queries for illustrating column alias
- To fetch ROLL_NO from Student table using CODE as alias name.
SELECT ROLL_NO AS CODE FROM Student;
Output:
CODE 1 2 3 4
- To fetch Branch using Stream as alias name and Grade as CGPA from table Student_Details.
SELECT Branch AS Stream,Grade as CGPA FROM Student_Details;
Output:
Stream CGPA Information Technology O Computer Science E Computer Science O Mechanical Engineering A
Queries for illustrating table alias
Generally table aliases are used to fetch the data from more than just single table and connect them through the field relations.
- To fetch Grade and NAME of Student with Age = 20.
SELECT s.NAME, d.Grade FROM Student AS s, Student_Details AS d WHERE s.Age=20 AND s.ROLL_NO=d.ROLL_NO;
Output:
NAME Grade SUJIT O
This article is contributed by Pratik Agarwal. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Improve Article
Save Article
Improve Article
Save Article
Aliases are the temporary names given to table or column for the purpose of a particular SQL query. It is used when name of column or table is used other than their original names, but the modified name is only temporary.
- Aliases are created to make table or column names more readable.
- The renaming is just a temporary change and table name does not change in the original database.
- Aliases are useful when table or column names are big or not very readable.
- These are preferred when there are more than one table involved in a query.
Basic Syntax:
- For column alias:
SELECT column as alias_name FROM table_name; column: fields in the table alias_name: temporary alias name to be used in replacement of original column name table_name: name of table
- For table alias:
SELECT column FROM table_name as alias_name; column: fields in the table table_name: name of table alias_name: temporary alias name to be used in replacement of original table name
Queries for illustrating column alias
- To fetch ROLL_NO from Student table using CODE as alias name.
SELECT ROLL_NO AS CODE FROM Student;
Output:
CODE 1 2 3 4
- To fetch Branch using Stream as alias name and Grade as CGPA from table Student_Details.
SELECT Branch AS Stream,Grade as CGPA FROM Student_Details;
Output:
Stream CGPA Information Technology O Computer Science E Computer Science O Mechanical Engineering A
Queries for illustrating table alias
Generally table aliases are used to fetch the data from more than just single table and connect them through the field relations.
- To fetch Grade and NAME of Student with Age = 20.
SELECT s.NAME, d.Grade FROM Student AS s, Student_Details AS d WHERE s.Age=20 AND s.ROLL_NO=d.ROLL_NO;
Output:
NAME Grade SUJIT O
This article is contributed by Pratik Agarwal. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Глава
3.
Базы данных
Практические
работы
Практическая работа № 13.
Работа с готовой таблицей
1. Откройте базу данных Учебники.odb[1] и
изучите её структуру. Сколько таблиц она содержит?
Ответ:
2. Откройте таблицу Учебники.
3.
Найдите любой
учебник, выпущенный издательством «Вита-Пресс».
4.
Используя «быстрый
фильтр» (фильтр по выделенному), найдите все учебники, которые выпустило
издательство «Вита-Пресс». Сколько записей было отобрано?
Ответ:
5.
Отсортируйте
отобранные записи в алфавитном порядке по полю Авторы, а учебники одного
и того же автора – по номеру класса (в порядке убывания). Покажите работу
учителю.
6.
Измените фильтр
так, чтобы отобрать все учебники по русскому языку издательства «Дрофа».
Сколько записей было отобрано?
Ответ:
7. Добавьте в базу данных информацию о
новом учебнике: Минаева С.С., Рослова Л.О., Рыдзе О.А. и. Математика. 1
класс. – М.: «Вентана-Граф», 2013.
8.
Используя
фильтр и сортировку[2],
определите, сколько учебников выпустили издательства «Дрофа», «Вита-Пресс»
и «Вентана-Граф» для 1-ого класса. Подсказка: программа автоматически
считает число выделенных записей.
Ответ:
Практическая работа № 14.
Создание однотабличной базы
данных
1. Создайте новую базу данных Футбол.
2.
Создайте
таблицу Футбол. В конструкторе добавьте следующие поля:
•
Команда (ключевое поле, размер поля – 20
символов)
•
Выигрыши
•
Ничьи
•
Проигрыши
•
Зарплата
Определите правильный тип данных
для каждого поля.
Ответ:
3.
Введите
следующие данные:
Команда |
Выигрыши |
Ничьи |
Проигрыши |
Зарплата |
Аметист |
10 |
7 |
3 |
13 290 р. |
Бирюза |
5 |
8 |
7 |
12 500 р. |
Восход |
13 |
5 |
2 |
22 000 р. |
Закат |
7 |
8 |
5 |
18 780 р. |
Коллектор |
11 |
6 |
3 |
20 200 р. |
Кубань |
6 |
12 |
2 |
14 000 р. |
Малахит |
12 |
3 |
5 |
17 340 р. |
Ротор |
8 |
12 |
0 |
15 820 р. |
Статор |
9 |
10 |
1 |
19 300 р. |
Финиш |
12 |
0 |
8 |
12 950 р. |
4.
Отсортируйте
записи по убыванию количества выигрышей.
5. Примените фильтр, который отбирает
только команды, имеющие более 10 побед и меньше 5 проигрышей. Сколько команд
отобрано с помощью этого фильтра?
Ответ:
Практическая работа № 15.
Создание запросов
При выполнении этой работы
используются база данных Футбол, с которой вы работали на предыдущем
уроке.
1.
Постройте
запрос с именем ЗапросЛучшие, который выводит все поля таблицы Футбол
для всех команд, имеющих более 8 побед и меньше 5 проигрышей. Команды должны
быть расставлены по убыванию числа побед. Сколько команд осталось в результатах
запроса?
Ответ:
Как выглядит этот запрос на языке SQL?
Ответ:
2.
Постройте
запрос с именем ЗапросОчки, который отбирает все поля из таблицы, кроме
поля Зарплата. Как выглядит этот запрос на языке SQL?
Ответ:
3.
Добавьте в этот
запрос вычисляемое поле Очки (за каждую победу команда получает 3 очка,
за ничью – 1 очко).
Как выглядит этот запрос на языке SQL?
Ответ:
4.
Отсортируйте
записи (с помощью запроса) так, чтобы на 1-ом месте стоял победитель (команда,
набравшая наибольшее количество очков). Какая команда оказалась на первом месте
и сколько очков она набрала?
Ответ:
Практическая работа № 16.
Создание формы
При
выполнении этой работы используются база данных Футбол, с которой вы
работали на предыдущих уроках.
1.
Постройте
форму на основе таблицы Футбол с помощью мастера.
2.
Добавьте на
форму изображение футбольного мяча (файл ball.jpg).
3.
Удалите надпись
«Команда» и выделите название команды жирным шрифтом увеличенного размера.
Внешний вид формы должен получиться примерно такой, как на рисунке справа.
4.
С помощью этой
формы добавьте в таблицу еще три записи:
Команда |
Выигрыши |
Ничьи |
Проигрыши |
Зарплата |
Зубр |
8 |
5 |
7 |
15 900 р. |
Тур |
10 |
5 |
6 |
12 300 р. |
Бизон |
15 |
3 |
3 |
18 700 р. |
5.
Проверьте,
появились и эти записи в таблице Футбол.
6.
Выполните
запрос ЗапросОчки и посмотрите, как изменилась ситуация в турнирной
таблице. Какая команда теперь на первом месте и сколько у неё очков?
Ответ:
Практическая работа № 17.
Оформление отчёта
При
выполнении этой работы используются база данных Футбол, с которой вы
работали на предыдущих уроках.
1.
Постройте отчет
Результаты на основе запроса ЗапросОчки с помощью мастера. Расположите
команды по убыванию количества набранных очков.
2.
Измените
внешний вид отчета так, как показано на рисунке. При редактировании отчёта в OpenOffice
Writer нужно добавить новый столбец Место и установить для ячейки
стиль нумерованного списка.
Практическая работа № 18.
Язык SQL
(Microsoft
Access)
Язык SQL (Structured Query Language) – это специальный язык для
управления данными. С его помощью можно полностью контролировать базу данных и
выполнять все операции, посылая запросы (команды) в текстовом виде. Таким
образом, например, можно управлять базой данных с удаленного компьютера.
В этой работе вы познакомитесь с
основными командами языка SQL:
CREATE TABLE создать
таблицу
SELECT выбрать
данные
UPDATE изменить
данные
DELETE удалить
данные
DROP удалить
таблицу
1. Создайте новую пустую базу данных SQLbase.accdb.
Создание
и заполнение таблиц
2.
Создайте запрос
в режиме конструктора и перейдите в режим SQL. Введите следующую команду для
создания таблицы:
CREATE TABLE [Туры]
(
[Код] INTEGER NOT
NULL PRIMARY KEY,
[Страна]
VARCHAR(50) NOT NULL,
[Транспорт]
VARCHAR(20) NOT NULL,
[Цена] MONEY NOT
NULL )
В этой команде требуется создать
таблицу (CREATE
TABLE) c именем «Туры». В таблице должно
быть 4 поля:
Код
– целое число (INTEGER),
непустое (NOT
NULL), первичный ключ таблицы (PRIMARY KEY)
Страна
– строка длиной до 50 символов, непустое
Транспорт
– строка длиной до
20 символов, непустое
Цена
– поле для
хранения денежной суммы (MONEY)
Названия таблиц и полей заключаются
в квадратные скобки! Если эти названия состоят из одного слова, скобки можно не
ставить:
CREATE TABLE Туры (
Код INTEGER NOT
NULL PRIMARY KEY,
Страна VARCHAR(50)
NOT NULL,
Транспорт
VARCHAR(20) NOT NULL,
Цена MONEY NOT
NULL)
3.
Выполните эту
команду (вкладка Конструктор – Выполнить). Проверьте, что таблица действительно
создана.
4.
Выполните
команду для добавления в базу новой записи:
INSERT
INTO Туры
VALUES (1, ‘Финляндия’,
‘автобус’, 1200)
Эта команда вставляет (INSERT)
в таблицу «Туры» одну запись. После ключевого слова VALUES в скобках
перечислены через запятую значения полей в том порядке, в котором они
задавались при создании таблицы.
Символьные строки в значениях полей
заключаются в апострофы или двойные кавычки!
5. Выполните ещё одно добавление
записи:
INSERT
INTO Туры
VALUES
(1, ‘Норвегия‘, ‘самолёт‘, 15000)
Какая ошибка произошла? В чём её
причина?
Ответ:
Исправьте ошибку и добавьте новую
запись правильно. В ответе запишите SQL-запрос.
Ответ:
6.
Аналогично
добавьте в таблицу ещё несколько записей:
Страна |
Транспорт |
Цена |
Швеция |
паром |
9000 р. |
Германия |
автобус |
15700 |
Греция |
самолёт |
23000 |
Норвегия |
автобус |
8000 р. |
Германия |
самолёт |
19000 |
Выбор
и сортировка данных
7.
Выполните
запрос на выборку данных:
SELECT * FROM Туры
Посмотрите на результат. Этот
оператор выберет все поля (*) всех записей из таблицы «Туры».
8.
Вместо * можно
указать через запятую список нужных полей:
SELECT
Страна, Цена FROM Туры
Проверьте результат выполнения этого запроса.
9. Чаще всего нужно выбрать только
записи, удовлетворяющие некоторому условию отбора. Для этого используется
ключевое слово WHERE,
после которого стоит условие:
SELECT * FROM Туры WHERE Страна = ‘Норвегия’
Проверьте работу этого оператора.
10. Составьте запрос, который выбирает
из таблицы «Туры» значения полей «Страна», «Транспорт» и «Цена»
для всех автобусных туров:
Ответ:
11.
Составьте
запрос, который выбирает из таблицы «Туры» значения всех полей для туров
c ценой меньше 10000 руб:
Ответ:
12. Для того, чтобы отсортировать
данные по некоторому полю, в запросе после ключевых слов ORDER BY (англ. «упорядочить
по») указывают название этого поля:
SELECT *
FROM Туры ORDER BY
Цена
Проверьте работу этого запроса.
Если в конце предыдущего запроса
добавить слово DESC
(англ. «descending» – нисходящий), сортировка
выполняется в обратном порядке.
13.
Составьте
запрос, который выбирает из таблицы «Туры» значения всех полей для туров
c ценой больше 10000 руб. и
сортирует результаты по убыванию цены:
Ответ:
14. В запросах можно использовать
стандартные функции. Например, функция MIN определяет минимальное значение
заданного поля среди всех записей:
SELECT
MIN(Цена) FROM Туры
Результат этого запроса – одно
число.
15.
Составьте
запрос, который находит минимальную цену для туров в Норвегию:
Ответ:
16.
Результаты
запросов можно использовать в других запросах – получается вложенный запрос.
Например, запрос
SELECT * FROM
Туры WHERE Цена =
(SELECT
MIN(Цена) FROM Туры WHERE Страна = ‘Норвегия’)
вернет данные о самом дешевом
туре.
17.
Составьте
запрос, который находит тур минимальной цены на самолёте:
Ответ:
Изменение
и удаление данных
18. Для изменения записей используется
оператор UPDATE.
Запрос, приведенный ниже, увеличивает цены всех туров на 10%:
UPDATE Туры SET Цена = Цена*1.1
Проверьте, что данные в таблице «Туры»
действительно изменились.
19. Авиакомпании в данный момент представляют
скидку на билеты, так что цены всех туров на самолётах составляют 80% от
исходных. Составьте и выполните соответствующий запрос.
Ответ:
Какая стоимость получилась у тура в
Грецию?
Ответ:
20. Скопируйте таблицу «Туры»,
назвав копию «Туры2». Удалите все туры в Германию с помощью запроса
DELETE FROM Туры2 WHERE Страна = ‘Германия’
Проверьте, что данные в таблице «Туры2»
действительно изменились.
21. Удалите таблицу «Туры2»,
которая больше не нужна, с помощью запроса
DROP TABLE Туры2
Проверьте, что таблица «Туры2»
удалена из списка таблиц.
Практическая работа № 19.
Построение таблиц в реляционной БД
1. Создайте новую базу данных Кафе.
Таблицы Блюда и Заказано
постройте с помощью конструктора.
1.
Запишите SQL—запрос для создания таблицы Заказы и выполните
его:
Ответ:
Примечание. Тип «дата» на языке SQL
записывается как DATE.
2. Установите связи между таблицами:
3. Заполните таблицы данными из §14
(рис. 3.16). Можно добавить и свои данные. Таблицу Заказы заполните с
помощью SQL-запросов. Запишите эти запросы в
следующем поле:
Ответ:
Примечание. Дата 03.11.2014 вводится на языке
SQL следующим образом:
– в OpenOffice Base как ‘2014-11-03’;
– в русской версии Microsoft Access как ‘03.11.2014’.
Практическая работа № 20.
Создание запросов к
реляционной базе данных
1.
Постройте
простой запрос ЗапросЗаказы, который собирает всю информацию о составе
сделанных заказов. Как выглядит этот запрос на языке SQL?
Ответ:
2. Объясните, как на языке SQL учитываются связи между таблицами?
Ответ:
3. Задайте псевдонимы (подписи) для
столбцов запроса. Как псевдонимы изменили SQL-запрос?
Ответ:
4.
Постройте
итоговый запрос ЗапросКОплате, который подсчитывает общую сумму оплату
по каждому из сделанных заказов. Как выглядит этот запрос на языке SQL?
Ответ:
5.
Объясните, как
выполняется на языке SQL суммирование цен отдельных блюд?
Ответ:
6.
Объясните, что
означают ключевые слова GROUP
BY на языке SQL?
Ответ:
Практическая
работа № 20-SQL.
Язык SQL (многотабличная база данных, OpenOffice Base)
В этой работе вы познакомитесь с
новой командой ALTER TABLE (изменить таблицу) языка SQL и научитесь составлять запросы к
многотабличной реляционной базе данных.
Создание и заполнение таблиц
1. Используя только SQL-запросы,
постройте три таблицы для реляционной базы данных кафе (значок обозначает первичный ключ таблицы):
2. Теперь нужно построить связи между
таблицами:
Для
этой цели используется команда ALTER
TABLE (англ. изменить таблицу). Построить связь между таблицами –
это значит задать ограничение (CONSTRAINT),
которое связывает первичный ключ одной таблицы с полем соответствующего типа
другой. Если связываемое поле второй таблицы – неключевое, то оно называется внешним
ключом (FOREIGN
KEY). Например, команда для создания связи 1:N между ключевым
полем Номер таблицы Заказы и неключевым полем Номер заказа
таблицы Заказано выглядит так:
ALTER TABLE
«Заказано»
ADD
CONSTRAINT ORDER_NO
FOREIGN
KEY(«Номер заказа»)
REFERENCES
«Заказы»(«Номер»)
Такая запись дословно означает:
Изменить
таблицу «Заказано»
добавить связь ORDER_NO
внешний ключ
«Номер заказа»
ссылается на поле
«Номер» таблицы «Заказы»
Здесь ORDER_NO – это просто
имя, которое мы выбрали для этой связи (можно было выбрать и другое).
3.
Введите и
выполните показанный выше SQL-запрос на добавление связи. Зайдите в меню Сервис
– Связи и убедитесь, что связь действительно создана[3].
4.
Составьте и
выполните SQL-запрос на добавление второй связи. Запишите этот запрос в поле
для ответа.
Ответ:
5. С помощью SQL-запросов заполните
базу следующими данными
Выбор данных и сортировка
6.
Построим в
режиме SQL запрос СоставЗаказа, который выводит номер заказа и название
заказанных блюд. Эти данные находятся в двух таблицах – Заказано и Блюда,
поэтому их нужно как-то объединить. Для этого используется связь 1:N между
таблицами, которую мы недавно установили. Действительно, для каждой записи в
таблице Заказано нужно выбрать название блюда из таблицы Блюда,
код которого совпадает с полем Заказано.Код блюда.
Это запрос на выборку данных,
поэтому используем оператор SELECT:
SELECT
«Заказано».»Номер заказа», «Блюда».»Название»
FROM
«Заказано», «Блюда»
WHERE
«Заказано».»Код блюда» = «Блюда».»Код»
Здесь из таблиц Заказано и Блюда
выбираются поля Номер заказа и Название; условие в последней
строке связывает таблицы.
Поскольку названия полей в
таблицах, из которых идет выбор, не совпадают, можно было записать запрос в
сокращенной форме, указав после оператора SELECT только названия
нужных полей:
SELECT «Номер
заказа», «Название»
FROM
«Заказано», «Блюда»
WHERE
«Заказано».»Код блюда» = «Блюда».»Код»
7. Теперь добавим в запрос дату
заказа. Она находится в таблице Заказы, которая пока в запросе не
участвует. Таким образом, нам нужно объединить три таблицы. Условие отбора
получается сложным, два условия (связи по коду блюда между таблицами Заказано
и Блюда и по номеру заказа между таблицами Заказы и Заказано)
объединяются с помощью логической операции AND (И):
SELECT «Номер
заказа», «Дата», «Название»
FROM
«Заказано», «Блюда», «Заказы»
WHERE
«Заказано».»Код блюда» = «Блюда».»Код»
AND
«Заказано».»Номер заказа» =
«Заказы».»Номер»
Проверьте результат выполнения
этого запроса.
8.
Измените запрос
так, чтобы он выбирал только блюда из состава заказа № 1. Запишите этот запрос:
Ответ:
9. Построим еще один запрос Итоги,
в котором для каждого заказа выводится его номер, дата и общая сумма (с помощью
функции SUM).
SELECT «Номер
заказа», «Дата», SUM(«Цена»)
FROM
«Заказано», «Блюда», «Заказы»
WHERE
«Заказано».»Код блюда» = «Блюда».»Код»
AND
«Заказано».»Номер заказа» =
«Заказы».»Номер»
GROUP BY «Номер заказа»,
«Дата»
В последней строке указано, что по
полям Номер заказа и Дата выполняется группировка, то есть сумма
цен считается для каждой уникальной пары «Номер заказа – Дата».
В таблице с результатами запроса
заголовок столбца с суммой выглядит не совсем понятно для пользователя:
«SUM(«Блюда».»Цена»)»
Для того, чтобы сделать у этого
столбца заголовок «Сумма», нужно добавить в первую строку запроса после
SUM(«Цена») так называемый псевдоним (подпись) с ключевым словом AS:
SELECT «Номер
заказа», «Дата», SUM(«Цена») AS «Сумма»
…
Проверьте результат выполнения
этого запроса. Псевдонимы можно задавать для всех значений, которые выводятся в
запросе.
10.
Измените запрос
так, чтобы заказы были отсортированы в порядке убывания суммы (используйте
ключевые слова ORDER
BY).
Ответ:
Вложенные запросы
11.
Построим запрос
МинСумма, который выводит минимальную сумму заказа. Для этого будем
использовать уже готовый запрос Итоги. Таким образом, источником данных
для запроса МинСумма будет не таблица, а другой запрос. Отметим, что
предварительно в запросе Итоги нужно отменить сортировку. Запрос
получается очень простым
SELECT MIN(«Сумма») AS
«Сумма» FROM «Итоги»
12. Наконец, можно вывести информацию о
заказе с минимальной суммой:
SELECT «Номер
заказа», «Дата», «Сумма»
FROM
«Итоги», «МинСумма»
WHERE
«Итоги».»Сумма» = «МинСумма».»Сумма»
Обратите внимание, что этот запрос
использует результаты выполнения двух ранее построенных запросов – Итоги
и МинСумма. Запрос Итоги можно было и не составлять, а вместо
этого использовать вложенный запрос (запрос в запросе):
SELECT «Номер
заказа», «Дата», «Сумма»
FROM «Итоги»
WHERE
«Сумма» =
(SELECT MIN(«Сумма«)
FROM «Итоги«)
Заметим, что если в базе данных
есть информация о нескольких заказах с такой же (минимальной) суммой, будет
показана информация обо всех этих заказах.
13.
Измените запрос
так, чтобы получить список всех заказов, сумма которых больше средней.
Ответ:
Практическая
работа № 20-SQLa.
Язык SQL (многотабличная база данных, MS
Access)
В этой работе вы познакомитесь с
новой командой ALTER TABLE (изменить таблицу) языка SQL и научитесь составлять запросы к
многотабличной реляционной базе данных.
Создание и заполнение таблиц
1. Используя только SQL-запросы,
постройте три таблицы для реляционной базы данных кафе (значок обозначает первичный ключ таблицы):
2. Теперь нужно построить связи между
таблицами:
Для
этой цели используется команда ALTER
TABLE (англ. изменить таблицу). Построить связь между таблицами –
это значит задать ограничение (CONSTRAINT),
которое связывает первичный ключ одной таблицы с полем соответствующего типа
другой. Если связываемое поле второй таблицы – неключевое, то оно называется внешним
ключом (FOREIGN
KEY). Например, команда для создания связи 1:N между ключевым
полем Номер таблицы Заказы и неключевым полем Номер заказа
таблицы Заказано выглядит так:
ALTER TABLE Заказано
ADD
CONSTRAINT ORDER_NO
FOREIGN
KEY([Номер заказа])
REFERENCES
Заказы(Номер)
Такая запись дословно означает:
Изменить таблицу
Заказано
добавить связь ORDER_NO
внешний ключ [Номер
заказа]
ссылается на поле
Номер таблицы Заказы
Здесь ORDER_NO – это просто
имя, которое мы выбрали для этой связи (можно было выбрать и другое).
3.
Введите и выполните
показанный выше SQL-запрос на добавление связи. Зайдите в меню Сервис –
Связи и убедитесь, что связь действительно создана[4].
4.
Составьте и
выполните SQL-запрос на добавление второй связи. Запишите этот запрос в поле
для ответа.
Ответ:
5. С помощью SQL-запросов заполните
базу следующими данными
Выбор данных и сортировка
6.
Построим в
режиме SQL запрос СоставЗаказа, который выводит номер заказа и название
заказанных блюд. Эти данные находятся в двух таблицах – Заказано и Блюда,
поэтому их нужно как-то объединить. Для этого используется связь 1:N между
таблицами, которую мы недавно установили. Действительно, для каждой записи в
таблице Заказано нужно выбрать название блюда из таблицы Блюда,
код которого совпадает с полем Заказано.Код блюда.
Это запрос на выборку данных,
поэтому используем оператор SELECT:
SELECT Заказано.[Номер
заказа], Блюда.Название
FROM Заказано, Блюда
WHERE Заказано.[Код блюда]
= Блюда.Код
Здесь из таблиц Заказано и Блюда
выбираются поля Номер заказа и Название; условие в последней
строке связывает таблицы.
Поскольку названия полей в
таблицах, из которых идет выбор, не совпадают, можно было записать запрос в
сокращенной форме, указав после оператора SELECT только названия
нужных полей:
SELECT [Номер заказа], Название
FROM Заказано, Блюда
WHERE Заказано.[Код блюда]
= Блюда.Код
7. Теперь добавим в запрос дату
заказа. Она находится в таблице Заказы, которая пока в запросе не
участвует. Таким образом, нам нужно объединить три таблицы. Условие отбора получается
сложным, два условия (связи по коду блюда между таблицами Заказано и Блюда
и по номеру заказа между таблицами Заказы и Заказано)
объединяются с помощью логической операции AND (И):
SELECT [Номер заказа], Дата, Название
FROM Заказано, Блюда,
Заказы
WHERE Заказано.[Код блюда]
= Блюда.Код
AND Заказано.[Номер
заказа] = Заказы.Номер
Проверьте результат выполнения
этого запроса.
8.
Измените запрос
так, чтобы он выбирал только блюда из состава заказа № 1. Запишите этот запрос:
Ответ:
9. Построим еще один запрос Итоги,
в котором для каждого заказа выводится его номер, дата и общая сумма (с помощью
функции SUM).
SELECT [Номер заказа],
Дата, SUM(Цена)
FROM Заказано, Блюда,
Заказы
WHERE Заказано.[Код блюда]
= Блюда.Код
AND Заказано.[Номер
заказа] = Заказы.Номер
GROUP BY [Номер заказа], Дата
В последней строке указано, что по
полям Номер заказа и Дата выполняется группировка, то есть сумма
цен считается для каждой уникальной пары «Номер заказа – Дата».
В таблице с результатами запроса
заголовок столбца с суммой выглядит не совсем понятно для пользователя,
например:
«Expr1002»
Для того, чтобы сделать у этого
столбца заголовок «Сумма», нужно добавить в первую строку запроса после
SUM(«Цена») так называемый псевдоним (подпись) с ключевым словом AS:
SELECT [Номер заказа],
Дата, SUM(Цена) AS Сумма
…
Проверьте результат выполнения
этого запроса. Псевдонимы можно задавать для всех значений, которые выводятся в
запросе.
10.
Измените запрос
так, чтобы заказы были отсортированы в порядке убывания суммы (используйте
ключевые слова ORDER
BY).
Ответ:
Вложенные запросы
11.
Построим запрос
МинСумма, который выводит минимальную сумму заказа. Для этого будем
использовать уже готовый запрос Итоги. Таким образом, источником данных
для запроса МинСумма будет не таблица, а другой запрос. Отметим, что
предварительно в запросе Итоги нужно отменить сортировку. Запрос
получается очень простым
SELECT MIN(Сумма) AS Сумма FROM
Итоги
12. Наконец, можно вывести информацию о
заказе с минимальной суммой:
SELECT [Номер заказа],
Дата, Итоги.Сумма
FROM Итоги, МинСумма
WHERE Итоги.Сумма = МинСумма.Сумма
Обратите внимание, что этот запрос
использует результаты выполнения двух ранее построенных запросов – Итоги
и МинСумма. Запрос МинСумма можно было и не составлять, а вместо
этого использовать вложенный запрос (запрос в запросе):
SELECT [Номер заказа],
Дата, Сумма
FROM Итоги
WHERE Сумма =
(SELECT MIN(Сумма) AS Сумма FROM Итоги)
Заметим, что если в базе данных
есть информация о нескольких заказах с такой же (минимальной) суммой, будет
показана информация обо всех этих заказах.
13.
Измените запрос
так, чтобы получить список всех заказов, сумма которых больше средней.
Ответ:
Практическая работа № 21.
Создание формы с подчинённой
1. Используя материал §21 учебника,
постройте форму, показанную на рис. 3.43.
Практическая работа № 22.
Создание отчёта с
группировкой
1. Используя материал §21 учебника,
постройте отчёт с группировкой, показанный на рис. 3.50.
Практическая работа № 23.
Нереляционные базы данных
В этой
работе мы познакомимся с документо-ориентированной СУБД MongoDB (http://www.mongodb.org). Эта СУБД
кроссплатформенная и относится к категории свободного программного обеспечения
(Open Source). Для управления данными
используется язык JavaScript.
Данные хранятся не в виде таблиц, а
в виде коллекций документов. Документ – это объект, имеющий
свойства, то есть пары «имя-значение». Главное свойство документа – это его идентификатор
(код), который всегда играет роль первичного ключа.
В одной коллекции могут быть
совершенно разные документы с разным набором свойств, это и отличает
документо-ориентированную БД от реляционной.
Информация об объекте записывается
в фигурных скобках, например:
{
name: «Вася», age: 16 }
Этот
объект имеет два свойства (поля) – свойство name со значением
«Вася» и свойство age
со значением 16. Такой текстовый формат записи называется JSON (англ. JavaScript Object Notation = запись объектов с помощью JavaScript).
Свойства объекта могут быть
списками значений (массивами), они перечисляются в квадратных скобках через запятую:
{ name: «Вася«, age: 16, lang:
[«C», «Pascal», «JavaScript»] }
Здесь
свойство lang
– массив, в котором записаны названия языков программирования.
Свойства могут сами быть объектами
со своими свойствами, например:
{
name: «Вася«,
family: { mother:
«Вера«, father: «Петя» }
}
Свойство family
содержит два внутренних свойства (поля): mother и father.
Начало
работы
1.
Запустите
программу mongo
в консольном режиме. Определите рабочую базу данных, выполнив команду db (от
англ. database = база данных)
db
Ответ:
2.
Мы построим
простую базу данных для блога в Интернете. Переключитесь на базу данных blog с
помощью команды
use blog
Если этой базы данных раньше не
было, она будет создана. Проверьте, что она действительно стала активной.
3.
Для добавления
объекта в коллекцию используется оператор insert (вставить):
db.posts.insert ( документ
)
Первая часть записи, «db»,
означает обращение к рабочей базе данных; вторая, «posts» — название
коллекции (если такой коллекции нет, она будет создана), в скобках записываются
свойства объекта-документа. В нашем примере в базе blog будет одна
коллекция posts
(сообщения, записи, «посты»). Для каждого поста нужно задать дату и текст.
Добавьте одну запись следующим образом[5]:
db.posts.insert (
{date:
new Date(«04/23/2013»), text: «Привет!»} )
Дата (свойство date) строится с
помощью функции Date;
ей передается символьная запись даты в формате, принятом в США
(месяц/день/год).
4.
Проверьте,
создана ли коллекция posts
с помощью команды, которая показывает все коллекции текущей базы:
show collections
5.
Проверьте,
добавлена ли запись, с помощью команды
db.posts.find()
которая ищет и показывает все
документы, входящие в коллекцию posts.
Для вывода в красивом формате можно дополнительно вызвать функцию pretty
(англ. приятный)
db.posts.find().pretty()
В этом случае, если список свойств
документа не помещается в одну строку, он выводится в столбик:
{
«_id»:
ObjectId(«5176abbc06a6380da34966a2»),
«date»:
ISODate(«2013-04-22T20:00:00Z»),
«text»:
«Привет!»
}
СУБД автоматически добавила поле «_id» (идентификатор, код), которое
представляет собой суррогатный первичный ключ и строится случайным образом с
помощью функции ObjectId.
Дата преобразована в формат Международной организации по стандартизации (ISO).
6. Если нужно, значение ключа
«_id»
можно задать
самостоятельно, какое мы хотим.
Удалим все документы
из коллекции командой remove:
db.posts.remove()
и добавим четыре новых поста в базу, указав явно идентификаторы[6]:
db.posts.insert
( {_id: 1, date: new Date(«04/23/2013»), text: «Привет!» }
)
db.posts.insert
( {_id: 2, date: new Date(«04/24/2013»), text: «Это второй пост.»
} )
db.posts.insert
( {_id: 3, date: new Date(«04/25/2013»), text: «Это третий пост.»
} )
db.posts.insert
( {_id: 4, date: new Date(«04/26/2013»), text: «Это четвёртый пост.»
} )
Убедитесь, что документы
действительно добавлены в коллекцию.
Поиск
7.
Для поиска
нужных документов используется уже знакомая нам функция find. В скобках можно
задать критерий поиска – это объект (записанный в фигурных скобках), который содержит
название поля и значение этого поля, которое мы ищем. Например, найдите документ
с кодом (идентификатором, _id), равным 2:
db.posts.find( {_id: 2} )
8.
В условиях
можно использовать не только строгие равенства, как в предыдущее примере, но
неравенства. Неравенство – это тоже объект, у которого специальное название
свойства, начинающееся знаком $:
$ne – не равно,
$lt – меньше, $lte – меньше или равно,
$gt – больше, $gte – больше или равно
Например, найдем записи с
идентификатором больше 2:
db.posts.find( {_id: {$gt: 2} } )
Сколько документов найдено?
Ответ:
9.
Найдем посты,
написанные 24.04.2013 или позднее:
db.posts.find({date:
{$gte: new Date(«04/24/2013»)} })
10.
Для поиска
можно использовать сразу несколько условий. Если все условия нужно выполнить
одновременно, их записывают как один объект с несколькими свойствами. Например,
следующий запрос находит все документы, у которых свойство «_id» больше 2, а дата
создания – не раньше 26.04.2013:
db.posts.find(
{ _id: {$gt: 2},
date:
{$gtе: new Date(«04/26/2013»)}
} )
11.
Самое мощное
средство поиска в MongoDB – это оператор $where, которому можно
передать строку в кавычках, задающую условие поиска на JavaScript, например,
db.posts.find( { $where:
«this._id > 2» } )
Здесь this – это объект
(документ), который требуется проверить; через точку записывается название
нужного поля. Оператору $where
можно передать любую функцию на JavaScript, которая возвращает логическое значение (истинное,
если условие отбора выполняется). Например, запрос, показанный в п. 10,
можно было записать так:
db.posts.find( { $where:
function()
{
return this._id > 2 &&
this.date >= new Date(«04/26/2013»)
}
} )
Пара символов && в языке JavaScript обозначает логическую операцию
«И», а символы || –
логическую операцию «ИЛИ». Проверка на равенство записывается как «==», а
условие «не равно» – как «!=».
12.
Составьте
запрос для поиска всех документов, у которых свойство _id равно 1 или дата создания равна
26.04.2013:
Ответ:
Сортировка
13.
Для сортировки
используется функция sort.
Она сортирует те документы, которые предварительно найдены с помощью find.
При вызове функции sort
в скобках указывается порядок сортировки – объект (в фигурных скобках),
содержащий название поля для сортировки; значение этого поля может быть 1
(сортировка по возрастанию) или «-1» (по убыванию).
Отсортируйте документы по
возрастанию даты
db.posts.find().sort(
{date: 1} )
а теперь по убыванию:
db.posts.find().sort(
{date: -1} )
Изменение
14.
Для изменения
документов используют команду update.
Допустим, мы хотим добавить к документу с идентификатором 1 новое логическое свойство
visible
(англ. видимый) и присвоить ему значение false (ложь), которое
означает, что это пост пока скрыт и выводить его на веб-страницу не нужно.
Функции update передаются два
объекта в фигурных скобках: условие, позволяющее найти нужный документ, и
свойства, которые у него нужно изменить. Попробуйте выполнить команду
db.posts.update(
{_id: 1}, {visible: false} )
и посмотрите, что получилось в
результате.
Ответ:
15.
Восстановите
исходный пост с кодом 1.
16.
Для того, чтобы
не заменять документ полностью, а изменить (или добавить) значение какого-то
поля, нужно использовать специальный объект со свойством $set (установить):
db.posts.update(
{_id: 1}, {$set: {visible: false}} )
Примените эту команду и проверьте
результат её выполнения.
Обратите
внимание, что сейчас в коллекции posts
находятся документы с разной структурой: один из них имеет свойство visible,
а остальные – нет. При этом никаких изменений в структуру базы данных вносить
не пришлось.
17.
Найдите все
документы, у которых свойство visible
равно false.
Какой запрос нужно для этого выполнить?
Ответ:
18.
Теперь выполним
множественное обновление: установим свойство visible равным true
(истина) для всех документов, для которых это свойство не установлено (или, что
то же самое, равно специальному нулевому значению null):
db.posts.update(
{visible: null},
{$set: {visible: true}}, {multi: true} )
Третий параметр – объект со
свойством multi
(англ. множественный), равным true (истина) разрешает изменение
нескольких документов сразу (если его не указать, будет изменён только один
документ – тот, который найден первым).
19.
Составьте
запрос для поиска всех документов, у которых свойство visible равно true,
а дата создания – не позднее 25.04.2013:
Ответ:
Проверьте результат его работы.
20.
Теперь добавим
к комментарии к одному из постов (с идентификатором 2). Заметьте, что благодаря
документо-ориентированной СУБД заранее планировать наличие комментариев не нужно
– мы можем добавлять новые свойства к любому документу «на ходу».
Комментариев может быть много,
поэтому новое свойство comments
будет массивом. Для добавления нового элемента в массив используется
специальный объект со свойство $push
(англ. втолкнуть):
db.posts.update( {_id: 2},
{$push: {comments:
«Комментарий 1»} })
db.posts.update( {_id: 2},
{$push: {comments:
«Комментарий 2»} })
db.posts.update( {_id: 2},
{$push: {comments: «Комментарий
3»} })
Когда выполняется первая из этих
команд, у документа с идентификатором 2 еще нет свойства comments – оно будет создано
автоматически.
21.
Все документы с
комментариями можно найти с помощью объекта со свойством $exists (существует):
var c =
db.posts.find( {comments: {$exists: true}} )
Результат этого запроса не
выводится на экран, а записывается в переменную c. Затем можно
определить его длину (число найденных документов) с помощью функции length
(англ. длина) и вывести на экран в цикле в формате JSON с помощью
функции printjson:
for(i =
0; i < c.length(); i++) printjson( c[i] )
Можно работать и с отдельными
свойствами, например, вывести на экран даты всех найденных постов с помощью
функции print:
for(i =
0; i < c.length(); i++) print( c[i].date )
Удаление
22.
Как вы уже
знаете, для удаления всех документов из коллекции используется команда remove.
Запишите команду, которая удаляет все документы из коллекции posts, но не
выполняйте её.
Ответ:
23.
С помощью
команды remove
можно удалять отдельные записи – условие для поиска нужных записей задается как
параметр функции. Например:
db.posts.remove( {_id: 4} )
Выполните эту команду и проверьте
её выполнение.
24.
Запишите
команду для удаления всех документов, у которых свойство visible установлено в
false
выполните её.
Ответ:
25. С помощью команды
drop вся
коллекция удаляется
из базы.
Например,
db.posts.drop()
26.
Объясните, в
чём отличие между командами remove()
и drop().
Ответ:
27.
Проверьте, что
коллекция posts
действительно была удалена. Какую команду нужно для этого использовать?
Ответ:
Дополнительная
информация:
- http://www.mongodb.org – официальный сайт разработки
MongoDB. - http://docs.mongodb.org/manual/installation/
– инструкция по установке MongoDB для разных операционных
систем. - http://jsman.ru/mongo-book/ – русский перевод книги K. Seguin «The Little
MongoDB Book».
Установка
MongoDB
Windows
- Скачайте архив с
программой со страницы http://www.mongodb.org/downloads - Распакуйте архив
в отдельный каталог в любом месте диска, например, в каталог C:MongoDB.
Внутри этого каталога должен появиться каталог bin, в котором
находятся все файлы СУБД. - Создайте новый
каталог, где будут храниться данные. Удобно создать это каталог прямо
внутри каталога C:MongoDB, например, C:MongoDBdata. - Создайте в
каталоге C:MongoDBbin командный файл start.bat с командой
запуска серверной части, в параметре dbpath указывается путь к
каталогу с базами данных:
C:MongoDBbinmongod.exe
—dbpath C:МongoDBdata
- Создайте
(например, на рабочем столе) ярлык на файл C:MongoDBbinstart.bat
для запуска серверной части. - Создайте
(например, на рабочем столе) ярлык на файл C:MongoDBbinmongo.exe
для запуска консоли (оболочки). - Запустите
серверную часть, затем запустите консоль.
Ubuntu
Установка
пакета
- В Терминале
введите следующую команду для импорта публичного GPG-ключа (http://docs.mongodb.org/10gen-gpg-key.asc):
sudo
apt-key adv —keyserver keyserver.ubuntu.com —recv 7F0CEB10
- Создайте файл /etc/apt/sources.list.d/10gen.list и добавьте в него строку для
обращения к репозиторию компании 10gen:
deb
http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen
- Перегрузите список репозиториев командой
sudo apt-get update
- Установите последнюю версию пакета командой
sudo apt-get install mongodb-10gen
Запуск
программы
- Запустите
серверную часть mongod как службу командой
sudo service mongodb start
- Запустите
командную оболочку (консоль) командой
mongo
Установка
на других ОС: http://docs.mongodb.org/manual/installation/
Практическая работа № 24.
Простая экспертная система
1. Выберите одну из предложенных тем (или
любую другую, которая вам близка) для своей экспертной системы:
·
«Анализ
неисправностей компьютера (автомобиля, велосипеда и т.п.)»
·
«Подбор
комплектующих для нового компьютера»
·
«Выбор места
отдыха во время отпуска»
·
«Выбор места рыбалки
в выходные»
·
«Выбор
материалов для строительства»
·
«Определение
типа корабля (самолёта, автомобиля)»
·
«Автомат, определяющий
задуманного артиста (политика, героя мультфильма и т.п.)»
·
…
2.
Постройте базу
знаний в виде дерева решений.
3.
Разработайте программу
на любом языке программирования (или постройте эту экспертную систему с помощью
любого готового программного средства).
Скачано с www.znanio.ru