> CREATE TABLE IF NOT EXISTS `users_rights` (
`id` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`rights` int(10) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
* где table
— имя таблицы (в примере users_rights
); field1, field2
— имя полей (в примере создается 3 поля — id, user_id, rights
); options1, options2
— параметры поля (в примере int(10) unsigned NOT NULL
); table options
— общие параметры таблицы (в примере ENGINE=InnoDB DEFAULT CHARSET=utf8
).
Использование запросов в PHP
Подключаемся к базе данных:
mysql_connect ("localhost", "login", "password") or die ("MySQL connect error");
mysql_select_db ("db_name");
mysql_query("SET NAMES "utf8"");
* где подключение выполняется к базе на локальном сервере (localhost
); учетные данные для подключения — login
и password
(соответственно, логин и пароль); в качестве базы используется db_name
; используемая кодировка UTF-8
.
Также можно создать постоянное подключение:
mysql_pconnect ("localhost", "login", "password") or die ("MySQL connect error");
* однако есть вероятность достигнуть максимально разрешенного лимита хостинга. Данным способом стоит пользоваться на собственных серверах, где мы сами можем контролировать ситуацию.
Завершить подключение:
* в PHP выполняется автоматически, кроме постоянных подключений (mysql_pconnect).
Запрос к MySQL (Mariadb) в PHP делается функцией mysql_query(), а извлечение данных из запроса — mysql_fetch_array():
$result = mysql_query("SELECT * FROM users");
while ($mass = mysql_fetch_array($result)) {
echo $mass . "
";
}
* в данном примере выполнен запрос к таблице users
. Результат запроса помещен в переменную $result
. Далее используется цикл while
, каждая итерация которого извлекает массив данных и помещает его в переменную $mass
— в каждой итерации мы работаем с одной строкой базы данных.
Используемая функция mysql_fetch_array() возвращает ассоциативный массив, с которым удобно работать, но есть еще альтернатива — mysql_fetch_row(), которая возвращает обычный нумерованный массив.
Экранирование
При необходимости включения в строку запроса спецсимвола, например, %, необходимо использовать экранирование с помощью символа обратного слэша — \
Например:
* если выполнить такой запрос без экранирования, знак %, будет восприниматься как любое количество символов после 100.
На этом все. Если Вам нужно помочь с выполнением запроса, пишите мне на почту
Содержание статьи
1.
Самые простые MySQL запросы
2.
Простые SELECT (выбрать) запросы
3.
Простые INSERT (новая запись) запросы
4.
Простые UPDATE (перезаписать, дописать) запросы
5.
Простые DELETE (удалить запись) запросы
6.
Простые DROP (удалить таблицу) запросы
7.
Сложные MySQL запросы
8.
MySQL запросы и переменные PHP
1. Самые простые SQL запросы
1. Выведет список ВСЕХ баз.
SHOW databases;
2. Выведет список ВСЕХ таблиц в Базе Данных base_name.
SHOW tables in base_name;
2. Простые SELECT (выбрать) запросы к базе данных MySQL
SELECT
– запрос, который выбирает уже существующие данные из БД. Для выбора можно указывать определённые параметры выбора. Например, суть запроса русским языком звучит так - ВЫБРАТЬ такие-то колонки ИЗ такой-то таблицы ГДЕ параметр такой-то колонки равен значению.1. Выбирает ВСЕ данные в таблице tbl_name.
SELECT * FROM tbl_name;
2. Выведет количество записей в таблице tbl_name.
SELECT count(*) FROM tbl_name;
3. Выбирает (SELECT) из(FROM) таблицы tbl_name лимит (LIMIT) 3 записи, начиная с 2.
SELECT * FROM tbl_name LIMIT 2,3;
4. Выбирает (SELECT) ВСЕ (*) записи из (FROM) таблицы tbl_name и сортирует их (ORDER BY) по полю id по порядку.
SELECT * FROM tbl_name ORDER BY id;
5. Выбирает (SELECT) ВСЕ записи из (FROM) таблицы tbl_name и сортирует их (ORDER BY) по полю id в ОБРАТНОМ порядке.
SELECT * FROM tbl_name ORDER BY id DESC;
6. Выбирает (SELECT
) ВСЕ (*) записи из (FROM
) таблицы users
и сортирует их (ORDER BY
) по полю id
в порядке возрастания, лимит (LIMIT
) первые 5 записей.
SELECT * FROM users ORDER BY id LIMIT 5;
7. Выбирает все записи из таблицы users
, где поле fname
соответствует значению Gena
.
SELECT * FROM users WHERE fname="Gena";
8. Выбирает все записи из таблицы users
, где значение поля fname
начинается с Ge
.
SELECT * FROM users WHERE fname LIKE "Ge%";
9. Выбирает все записи из таблицы users
, где fname
заканчивается на na
, и упорядочивает записи в порядке возрастания значения id
.
SELECT * FROM users WHERE fname LIKE "%na" ORDER BY id;
10. Выбирает все данные из колонок fname
, lname
из таблице users
.
SELECT fname, lname FROM users;
11.
Допустим у Вас в таблице пользовательских данных есть страна. Так вот если Вы хотите вывести ТОЛЬКО список встречающихся значений (чтобы, например, Россия не выводилось 20 раз, а только один), то используем DISTINCT. Выведет, из массы повторяющихся значений Россия, Украина, Беларусь. Таким образом, из таблицы users
колонки country
будут выведены ВСЕ УНИКАЛЬНЫЕ значения
SELECT DISTINCT country FROM users;
12. Выбирает ВСЕ данные строк из таблицы users
где age
имеет значения 18,19 и 21.
SELECT * FROM users WHERE age IN (18,19,21);
13.
Выбирает МАКСИМАЛЬНОЕ значение age
в таблице users
. То есть если у Вас в таблице самое большее значение age
(с англ. возраст) равно 55, то результатом запроса будет 55.
SELECT max(age) FROM users;
14. Выберет данные из таблицы users
по полям name
и age
ГДЕ age
принимает самое маленькое значение.
SELECT name, min(age) FROM users;
15. Выберет данные из таблицы users
по полю name
ГДЕ id
НЕ РАВЕН 2.
SELECT name FROM users WHERE id!="2";
3. Простые INSERT (новая запись) запросы
INSERT
– запрос, который позволяет ПЕРВОНАЧАЛЬНО вставить запись в БД. То есть создаёт НОВУЮ запись (строчку) в БД.1.
Делает новую запись в таблице users
, в поле name
вставляет Сергей, а в поле age
вставляет 25. Таким образом, в таблицу дописывается новая строки с данными значениями. Если колонок больше, то они оставшиеся останутся либо пустыми, либо с установленными по умолчанию значениями.
INSERT INTO users (name, age) VALUES ("Сергей", "25");
4. Простые UPDATE запросы к базе данных MySQL
UPDATE
– запрос, который позволяет ПЕРЕЗАПИСАТЬ значения полей или ДОПИСАТЬ что-то в уже существующей строке в БД. Например, есть готовая строка, но в ней нужно перезаписать параметр возраста, так как он изменился со временем. 1. В таблице users
age
становится 18.
UPDATE users SET age = "18" WHERE id = "3";
2.
Всё то же самое, что и в первом запросе, просто показан синтаксис запроса, где перезаписываются два поля и более.
В таблице users
ГДЕ id равно 3 значение поля age
становится 18, а country
Россия.
UPDATE users SET age = "18", country = "Россия" WHERE id = "3";
5. Простые DELETE (удалить запись) запросы к базе данных MySQL
DELETE
– запрос, который удаляет строку из таблицы.1. Удаляет строку из таблицы users
ГДЕ id
равен 10.
DELETE FROM users WHERE id = "10";
6. Простые DROP (удалить таблицу) запросы к базе данных MySQL
DROP
– запрос, который удаляет таблицу.1. Удаляет целиком таблицу tbl_name
.
DROP TABLE tbl_name;
7. Сложные запросы к базе данных MySQL
Любопытные запросы, которые могут пригодиться даже опытным пользователямSELECT id,name,country FROM users,admins WHERE TO_DAYS(NOW()) - TO_DAYS(registration_date) <= 14 AND activation != "0" ORDER BY registration_date DESC;
Данный сложный запрос ВЫБИРАЕТ колонки id,name,country
В ТАБЛИЦАХ users,admins
ГДЕ registration_date
(дата) не старше 14
дней И activation
НЕ РАВНО 0
, СОРТИРОВАТЬ по registration_date
в обратном порядке (новое в начале).
UPDATE users SET age = "18+" WHERE age = (SELECT age FROM users WHERE male = "man");
Выше указан пример так называемого запроса в запросе
в SQL. Обновить возраст среди пользователей на 18+, где пол - мужской. Подобные варианты запроса не рекомендую. По личному опыту скажу, лучше создать несколько отдельных - они будут прорабатываться быстрее.
8. Запросы к базе данных MySQL и PHP
В MySQL запросы в PHP странице можно вставлять переменные в качестве сравниваемых и тп значений. Пара примеров1. Выбирает все записи из таблицы users
, где поле fname
соответствует значению переменной $name
.
SELECT * FROM users WHERE fname="$name";
2. В таблице users
ГДЕ id равно 3 значение поля age
изменяется на значение переменной $age.
UPDATE users SET age = "$age" WHERE id = "3";
Внимание!
Если Вам интересен какой-либо ещё пример, то пишите вопрос в комментарии!
SQL - один из самых распространенных языков программирования, для создания и управления базой данных, а также для проведения разнообразных действий с самими данными.
Как показывает практика, он довольно простой в освоении и максимально использует стандартную лексику английского языка. Как и любой другой язык программирования, SQL имеет собственную логику и синтаксис, набор основных команд и правила их использования.
Классификация команд языка SQL
Все стандартные можно рассматривать исходя из их назначения. Как основу внегласной классификации можно взять такие наборы, как:
Команды для построения запросов.
Команды встроенных процедур и функций.
Команды триггеров и системных таблиц.
Наборы комбинаций для работы с датой и строковыми переменными.
Команды для работы с данными и таблицами.
Данную классификацию можно продолжать до бесконечности, но основные наборы команды языка SQL будут построены именно исходя из этих типов.
Рассматривая классификацию языка, нельзя не упомянуть о том, что он является универсальным, о чем говорит сфера его использования. Этот язык программирования и его разновидности задействуются не только в стандартной среде, но и в других программах, которые, так или иначе, вы использовали.
Сферу использования SQL можно рассматривать с точки зрения офисного программного обеспечения, а именно MicrosoftAccess. Этот язык, а точнее, его разновидность — MySQL, позволяет администрировать базы данных в сети Internet. Даже среда разработки Oracle использует в основе своих запросов команды SQL.
Использование SQL в MicrosoftAccess
Одним из самых простых примеров использования языка для программирования баз данных считается пакет программного обеспечения MicrosoftOffice. Изучение этого программного продукта предусмотрено школьным курсом информатики, а в одиннадцатом классе рассматривается система управления базой данных MicrosoftAccess.
Именно при изучении этого приложения ученики знакомятся с языком разработки баз данных и получают базовое понимание всего в него входящего. SQL команды Access довольно примитивны, конечно же, если рассматривать их на профессиональном уровне. Выполнение таких команд очень простое, а создаются они в приспособленном редакторе кода.
Рассмотрим конкретный пример:
SELECT Pe_SurName
WHERE Pe_Name = "Мэри";
Исходя из синтаксиса команды можно понять, что она вернет пользователю фамилию человека, в данном случае женщины по имени Мэри, которая хранится в таблице базы данных Contacts.
Хоть и использование SQL в Access ограничено, иногда такие простые запросы очень сильно могут упростить выполнение поставленного задания.
Использование команд SQL в Oracle
Oracle - это, наверное, единственный серьезный конкурент Microsoft SQL Server. Именно данная среда разработки и управления постоянно приводит к совершенствованию функций программного продукта компании Microsoft, так как конкуренция - это двигатель прогресса. Несмотря на постоянное соперничество, команды SQL Oracle повторяют SQL. Стоит отметить, что хоть Oracle и считается практически полной копией SQL, логика этой системы и языка в целом считается проще.
Система Oracle при использовании определенного набора команд не имеет такой сложной структуры. Если рассматривать возможности данных сред разработки баз данных, Oracle не имеет сложной структуры вложенных запросов.
Такая разница позволяет во много раз ускорить работу с данными, но, в противовес, ведет к нерациональному использованию памяти, в некоторых отдельных случаях. Структура Oracle в основном построена на временных таблицах и их использовании. Как пример: команды SQL в данной системе строятся по аналогии со стандартами самого языка SQL, хотя незначительно и отличаются от него.
SELECTCONCAT(CONCAT(CONCAT(‘Сотрудник ‘, sname), CONCAT(SUBSTR(fname, 0, 1), SUBSTR(otch, 0, 1))), CONCAT(‘принятнаработу ‘, acceptdate)) FROM employees WHERE acceptdate > to_date(‘01.01.80′,’dd.mm.yyyy’);
Данный запрос вернет данные о сотрудниках, которые приняты на работу в определенный промежуток времени. Хоть структура запроса отличается, от выполнение команд SQL в этих системах похоже, за исключением мелких деталей.
Использование SQL в сети Internet
С появлением всемирной паутины, то есть интернета, сфера использования языка SQL расширяется. Как известно, в сети хранится масса информации, но она не хаотично расположена, а размещена на сайтах и серверах по определенным критериям.
За хранение информации в Интернете, как и в других местах, отвечают непосредственно базы данных, а сайты являются системами управления. Как правило, сайты и их программный код организованы на разных языках программирования, но в основе баз данных лежит одна из разновидностей SQL, а именно язык создания баз данных, ориентированный под веб-интерфейсы MySQL.
Синтаксис и основной набор команд этого языка полностью копируют привычный всем SQL, но с некоторыми своими дополнениями, которые и дают ему отличие от Microsoft tSQL Server.
Команды SQL полностью похожи не только по синтаксису, но и по стандартному набору служебных слов. Разница состоит только в вызове и структурировании запроса. Для примера можно рассмотреть запрос для создания новой таблицы, именно она является первым, чему учат детей в школах на информатике:
$link = mysqli_connect("localhost", "root", "", "tester");
if (!$link) die("Error");
$query = "create table users(
login VARCHAR(20),
password VARCHAR(20)
if (mysqli_query($link, $query)) echo "Таблица создана.";
elseecho "Таблица не создана: ".mysqli_error();
mysqli_close($link);
В результате выполнения такого запроса можно получить новую таблицу "Юзеры", в которой будет два поля: логин и пароль.
Синтаксис изменен под Вэб, но в основу положены команды MicrosoftSQLServer.
Построение запросов MicrosoftSQLServer
Выборка из таблиц определенного набора данных одна из основных задач SQL. Для таких операций предусмотрена команда select в SQL. Именно о ней пойдет речь ниже.
Правила построение команды очень просты, а сама команда select в SQL строится следующим образом. К примеру, есть таблица, в которой имеются данные о сотруднике, которая, к примеру, имеет имя Person. Поставим задачу, что из таблицы нужно выбрать данные о сотрудниках, дата рождения которых - в промежутке от первого января до первого марта текущего года включительно. Для такой выборки необходимо выполнить команду SQL, в которой будет не только стандартная конструкция, но и условие выбора:
Select * from Person
Where P_BerthDay >= ‘01/01/2016’ and P_BerthDay<= ‘03/01/2016’
Выполнение такой команды вернет все данные о сотрудниках, день рождения которых находится в том периоде, который был задан вами. Иногда может стоять задача вывести только фамилию, имя и отчество сотрудника. Для этого запрос нужно построить чуть иначе, например, таким образом:
SelectP_Name - имя
P_SurName - фамилия
P_Patronimic - отчество
Where P_BerthDay >= ‘01/01/2016’ and P_BerthDay<= ‘03/01/2016’
Однако это всего лишь выбор чего-либо. Он, по сути своей, не влияет ни на что, а лишь предоставляет информацию. Но если вы решили заняться языком SQL всерьез, вам придется научится вносить изменения в базы данных, так как их построение без этого попросту невозможно. Как это делается, будет рассмотрено чуть ниже.
Основные команды SQL для изменения данных
Синтаксис языка построен не только для выполнения запросов, но и для манипуляций с данными. В основном задачей программиста баз данных является написание скриптов для выборок и отчетов, но иногда необходимо вносить правки в таблицы. Список команд SQL для таких действий невелик и состоит из трех основных команд:
Insert (пер. Вставить).
Update (пер. Обновление).
Delete (пер. Удалить).
Назначение этих команд легко определить, для этого достаточно будет всего лишь перевести их название. Эти команды просты в использовании и имеют не сложную схему построения, но стоит упомянуть, что некоторые из них, при неправильном использовании, могут нанести непоправимый вред базе.
Как правило, перед использованием такие MSSQL команды нужно продумать, и учесть все возможные последствия их выполнения.
Выучив данные команды, вы сможете полноценно начать работу с таблицами баз данных, тем самым видоизменять ее и вносить какие-то новые перменные или же удалять старые.
Команда Insert
Для вставки данных в таблицу используется самая безопасная команда — Insert. Неправильно вставленные данные всегда можно удалить и внести в базу данных заново.
Команда Insert предназначена для вставки в таблицу новых данных и позволяет добавить как полный набор, так и выборочно.
Для примера рассмотрим команду вставки в ранее описанную таблицу Person. Для того чтобы внести данные в таблицу необходимо выполнить команду SQL, которая позволит вставить все данные в таблицу или заполнить ее выборочно.
Insert into person
Select ‘Григорьев’,’Виталий’,’Петрович’,’01/01/1988’
Команды такого плана автоматически заполняют все ячейки таблицы с указанными данными. Бывают ситуации, когда у сотрудника нет отчества, скажем, он по обмену приехал работать из Германии. В таком случае нужно выполнить команду вставки данных, которая занесет в таблицу только то, что необходимо. Синтаксис такой команды будет следующим:
Insertintoperson(P_Name, P_SurName ,P_BerthDay)
Values (‘Дэвид’, ‘Гук’,’02/11/1986’)
Такая команда заполнит только указанные ячейки, а все остальные будут иметь значение null.
Команда для изменения данных
Для изменения данных как всей строки, так и некоторых ячеек используется команда Update SQL. Выполнять такую команду нужно только с определенным условием, а именно точно указывать в какую строку по номеру необходимо внести изменения.
Команда Update SQL имеет несложный синтаксис. Для правильного использования необходимо указать, какие данные, в какой колонке и в какой записи стоит изменить. Далее составить скрипт и выполнить его. Рассмотрим пример. Нужно изменить дату рождения Дэвида Гука, который внесен в таблицу сотрудников под номером 5.
Set P_BerthDay = ’02/10/1986’ where P_ID = 5
Условие (в данном скрипте) не даст изменить дату рождения во всех записях таблицы, а обновит только нужные.
Именно этой командой программисты пользуются чаще всего, так как она позволяет изменять данные в таблице не нанося существенный вред всей информации.
Команды для использования встроенных процедур и функций
С помощью языка SQL можно не только строить запросы, но и создавать встроенные механизмы для работы с данными. Как правило, бывают моменты, когда нужно использовать в теле одного запроса выборку, написанную ранее.
Если судить логически, то нужно скопировать текст выборки и вставить в нужное место, но можно обойтись и более простым решением. Рассмотрим пример, когда на рабочем интерфейсе выведена кнопка для печати отчета, скажем в Excel. Эта операция будет выполняться по мере необходимости. Для таких целей служат встроенные хранимые процедуры. Команды в данном случае, заключаются в процедуру и вызываются с помощью команды SQLExec.
Предположим, что была создана процедура для вывода даты рождения сотрудников с ранее описанной таблицы Person. В таком случае нет необходимости писать весь запрос. Для получения необходимой информации достаточно выполнить команду Exec [имя процедуры] и передать необходимые для выборки параметры. Как пример можно рассмотреть механизм создания процедуры такого характера:
CREATEPROCEDUREPrintPerson
@DB smalldatetime
@DE smalldatetime
SELECT * from Person
FROM HumanResources.vEmployeeDepartmentHistory
WHERE P_BerthDay >= @DB and P_BerthDay <= @DE
ANDEndDateISNULL;
Данная процедура вернет все сведения о сотрудниках, день рождения которых будет находиться в заданном временном периоде.
Организация целостности данных. Триггеры
Некоторые MS SQL-команды, можно даже сказать, конструкции, позволяют не только организовать манипуляции с данными, но и обеспечить их целостность. Для таких целей в языке предназначены системные конструкции, которые создает сам программист. Это так называемые триггеры, которые смогут обеспечить контроль данных.
В этом случае для организации проверки условий используются стандартные команды SQL-запросов. В триггерах можно создавать массу условий и ограничений для работы с данными, которые помогут управлять не только доступом к информации, но и запретить удаление, изменение или вставку данных.
Типы команд SQL, которые можно использовать в триггере, не ограничены. Рассмотрим на примере.
Если описывать механизм создания триггера, то типы команд SQL здесь такие же, как при создании процедуры. Сам алгоритм будет описан ниже.
Первым делом нужно описать служебную команду для создания триггеров:
Указываем, для какой операции с данными (в нашем случае это операция изменения данных).
Следующим шагом будет указание таблиц и переменных:
declare @ID int. @Date smalldatetime @nID int. @nDatesmalldatetime
DEclare cursor C1 for select P_ID, P_BerthDay from Inserted
DEclare cursor C2 for select P_ID, P_BerthDay from deleted
Задаем шаги выбора данных. После, в теле курсоров прописываем условие и реакцию на него:
if @ID = @nID and @nDate = "01/01/2016"
sMasseges "Выполнить операцию невозможно. Дата не подходит"
Стоит упомянуть о том, что триггер можно не только создать, но и отключить на время. Такую манипуляцию может провести только программист, выполнив команды SQL SERVER:
altertablePERSONdisabletriggerall - для отключения всех триггеров, созданных для данной таблицы, и, соответственно, altertablePERSONenabletriggerall - для их включения.
Эти основные команды SQL используются чаще всего, но их комбинации могут быть самыми разнообразными. SQL - очень гибкий язык программирования и дает разработчику максимум возможностей.
Вывод
Из всего вышесказанного можно сделать единственный вывод: знание языка SQL просто необходимо тем, кто собирается всерьез заняться программированием. Он лежит в основе всех выполняемых операций как в интернете, так и в домашних базах данных. Именно поэтому будущий программист обязательно должен знать множество команд данного языка, так как лишь с их помощью можно, так сказать, общаться с компьютером.
Конечно, недостатки есть, как и во всем в этом мире, но они настолько незначительны, что просто меркнут перед достоинствами. Среди всех языков программирования SQL практически единственная в своем роде, ведь она является универсальной, и знания по написанию скриптов и кодов лежат в основе практически всех сайтов.
Главным достоинством SQL безоговорчно можно считать его простоту, ведь, как-никак, именно он внесен в школьную программу. С ним может справиться даже начинающий программист, толком не разбирающийся в языках.
Типы
данных
SQL
(Как в
Pg
, как в стандарте)
Строковые типы
Числовые типы данных
Денежные, Символьные, Двоичные типы
данных
Логический
тип. Перечисления
Примеры простейших SQL-запросов
Простейшие
SELECT-запросы
Оператор
SELECT (выбрать) языка SQL является самым
важным и самым часто используемым
оператором. Он предназначен для выборки
информации из таблиц базы данных.
Упрощенный синтаксис оператора SELECT
выглядит следующим образом.
SELECT [ ALL | DISTINCT ] select_item_commalist
FROM table_reference_commalist
[ WHERE conditional_expression ]
[ GROUP BY column_name_commalist ]
[ HAVING conditional_expression ]
[ ORDER BY order_item_commalist ]
В
квадратных скобках указаны элементы,
которые могут отсутствовать в запросе.
Ключевое
слово SELECT сообщает базе данных, что
данное предложение является запросом
на извлечение информации.
После
слова SELECT через запятую перечисляются
наименования полей (список атрибутов),
содержимое которых запрашивается.
Обязательным
ключевым словом в предложении-запросе
SELECT является слово FROM (из). За ключевым
словом FROM указывается список разделенных
запятыми имен таблиц, из ко-торых
извлекается информация.
Например,
select title, description from film
Любой
SQL-запрос должен заканчиваться символом
«;» (точка с запятой). Результатом данного
запроса будет таблица...
Порядок
следования столбцов в этой таблице
соответствует порядку полей, указанному
в запросе
Если
необходимо вывести значения всех,
столбцов таблицы, то можно вместо
перечисления их имен использовать
символ «*» (звездочка).
SELECT
* FROM film;
В
данном случае результатом выполнения
запроса будет вся таблица film.
Еще
раз обратим внимание на то, что получаемые
в результате SQL-запроса таблицы не в
полной мере отвечают определению
реляционного отношения. В частности,
в них могут оказаться кортежи (строки)
с одинаковыми значениями атрибутов.
Например,
запрос «список имен актеров», можно
записать в следующем виде.
select
first_name from actor;
Его
результатом будет таблица, в таблице
встречаются одинаковые строки. Для
исключения из результата SELECT-запроса
повторяющихся записей используется
ключевое слово DISTINCT (отличный).
Если
запрос SELECT извлекает множество полей,
то DISTINCT исключает дубликаты строк, в
которых значения всех выбранных полей
идентичны.
Предыдущий
запрос можно записать в следующем виде.
select
distinct first_name from actor;
В
результате получим таблицу, в которой
дубликаты строк исключены.
Ключевое
слово ALL (все), в отличие от DISTINCT, оказывает
противоположное действие, то есть при
его использовании повторяющиеся строки
включаются в состав выходных данных.
Режим, задаваемый ключевым словом ALL,
действует по умолчанию, поэтому в
реальных запросах для этих целей оно
практически не используется.
Использование
в операторе SELECT предложения, определяемого
ключевым словом WHERE (где), позволяет
задавать выражение условия (предикат),
принимающее значение истина или ложь
для значений полей строк таблиц, к
которым обращается оператор SELECT.
Предложение WHERE определяет, какие строки
указанных таблиц должны быть выбраны.
В таблицу, яв-ляющуюся результатом
запроса, включаются только те строки,
для которых условие (предикат), указанное
в предложении WHERE, принимает значение
истина.
Пример:
Написать запрос, выполняющий выборку
фамилий всех актеров с именем PENELOPE
select
last_name from actor
where
first_name="PENELOPE";
В
задаваемых в предложении WHERE условиях
могут использоваться операции сравнения,
определяемые операторами = (равно), >
(больше), < (меньше), >= (больше или
равно), <- (меньше или равно), <> (не
равно), а также логические операторы
AND, OR И NOT.
Например,
запрос для получения названий и описаний
фильмов - короткометражек (короче 60
мин), прокат которых стоит меньше 3$ ,
будет выглядеть таким образом:
select
title, description from film
where
length < 60 and rental_rate < 3
Результат
выполнения этого запроса имеет вид:
rental
- прокат
inventory
- опись, запасы
store- запас, магазин
Табличными выражениями
называются подзапросы, которые используются там, где ожидается наличие таблицы. Существует два типа табличных выражений:
Эти две формы табличных выражений рассматриваются в следующих подразделах.
Производные таблицы
Производная таблица (derived table)
- это табличное выражение, входящее в предложение FROM запроса. Производные таблицы можно применять в тех случаях, когда использование псевдонимов столбцов не представляется возможным, поскольку транслятор SQL обрабатывает другое предложение до того, как псевдоним станет известным. В примере ниже показана попытка использовать псевдоним столбца в ситуации, когда другое предложение обрабатывается до того, как станет известным псевдоним:
USE SampleDb;
SELECT MONTH(EnterDate) as enter_month
FROM Works_on
GROUP BY enter_month;
Попытка выполнить этот запрос выдаст следующее сообщение об ошибке:
Msg 207, Level 16, State 1, Line 5
Invalid column name "enter_month".
(Сообщение 207: уровень 16, состояние 1, строка 5
Недопустимое имя столбца enter_month)
Причиной ошибки является то обстоятельство, что предложение GROUP BY обрабатывается до обработки соответствующего списка инструкции SELECT, и при обработке этой группы псевдоним столбца enter_month неизвестен.
Эту проблему можно решить, используя производную таблицу, содержащую предшествующий запрос (без предложения GROUP BY), поскольку предложение FROM исполняется перед предложением GROUP BY:
USE SampleDb;
SELECT enter_month
FROM (SELECT MONTH(EnterDate) as enter_month
FROM Works_on)
AS m
GROUP BY enter_month;
Результат выполнения этого запроса будет таким:
Обычно табличное выражение можно разместить в любом месте инструкции SELECT, где может появиться имя таблицы. (Результатом табличного выражения всегда является таблица или, в особых случаях, выражение.) В примере ниже показывается использование табличного выражения в списке выбора инструкции SELECT:
Результат выполнения этого запроса:
Обобщенные табличные выражения
Обобщенным табличным выражением (OTB) (Common Table Expression - сокращенно CTE)
называется именованное табличное выражение, поддерживаемое языком Transact-SQL. Обобщенные табличные выражения используются в следующих двух типах запросов:
нерекурсивных;
рекурсивных.
Эти два типа запросов рассматриваются в следующих далее разделах.
OTB и нерекурсивные запросы
Нерекурсивную форму OTB можно использовать в качестве альтернативы производным таблицам и представлениям. Обычно OTB определяется посредством предложения WITH
и дополнительного запроса, который ссылается на имя, используемое в предложении WITH. В языке Transact-SQL значение ключевого слова WITH неоднозначно. Чтобы избежать неопределенности, инструкцию, предшествующую оператору WITH, следует завершать точкой с запятой.
USE AdventureWorks2012;
SELECT SalesOrderID
FROM Sales.SalesOrderHeader
WHERE TotalDue > (SELECT AVG(TotalDue)
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) = "2005")
AND Freight > (SELECT AVG(TotalDue)
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) = "2005")/2.5;
Запрос в этом примере выбирает заказы, чьи общие суммы налогов (TotalDue) большие, чем среднее значение по всем налогам, и плата за перевозку (Freight) которых больше чем 40% среднего значения налогов. Основным свойством этого запроса является его объемистость, поскольку вложенный запрос требуется писать дважды. Одним из возможных способов уменьшить объем конструкции запроса будет создать представление, содержащее вложенный запрос. Но это решение несколько сложно, поскольку требует создания представления, а потом его удаления после окончания выполнения запроса. Лучшим подходом будет создать OTB. В примере ниже показывается использование нерекурсивного OTB, которое сокращает определение запроса, приведенного выше:
USE AdventureWorks2012;
WITH price_calc(year_2005) AS
(SELECT AVG(TotalDue)
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) = "2005")
SELECT SalesOrderID
FROM Sales.SalesOrderHeader
WHERE TotalDue > (SELECT year_2005 FROM price_calc)
AND Freight > (SELECT year_2005 FROM price_calc)/2.5;
Синтаксис предложения WITH в нерекурсивных запросах имеет следующий вид:
Параметр cte_name представляет имя OTB, которое определяет результирующую таблицу, а параметр column_list - список столбцов табличного выражения. (В примере выше OTB называется price_calc и имеет один столбец - year_2005.) Параметр inner_query представляет инструкцию SELECT, которая определяет результирующий набор соответствующего табличного выражения. После этого определенное табличное выражение можно использовать во внешнем запросе outer_query. (Внешний запрос в примере выше использует OTB price_calc и ее столбец year_2005, чтобы упростить употребляющийся дважды вложенный запрос.)
OTB и рекурсивные запросы
В этом разделе представляется материал повышенной сложности. Поэтому при первом его чтении рекомендуется его пропустить и вернуться к нему позже. Посредством OTB можно реализовывать рекурсии, поскольку OTB могут содержать ссылки на самих себя. Основной синтаксис OTB для рекурсивного запроса выглядит таким образом:
Параметры cte_name и column_list имеют такое же значение, как и в OTB для нерекурсивных запросов. Тело предложения WITH состоит из двух запросов, объединенных оператором UNION ALL
. Первый запрос вызывается только один раз, и он начинает накапливать результат рекурсии. Первый операнд оператора UNION ALL не ссылается на OTB. Этот запрос называется опорным запросом или источником.
Второй запрос содержит ссылку на OTB и представляет ее рекурсивную часть. Вследствие этого он называется рекурсивным членом. В первом вызове рекурсивной части ссылка на OTB представляет результат опорного запроса. Рекурсивный член использует результат первого вызова запроса. После этого система снова вызывает рекурсивную часть. Вызов рекурсивного члена прекращается, когда предыдущий его вызов возвращает пустой результирующий набор.
Оператор UNION ALL соединяет накопившиеся на данный момент строки, а также дополнительные строки, добавленные текущим вызовом рекурсивного члена. (Наличие оператора UNION ALL означает, что повторяющиеся строки не будут удалены из результата.)
Наконец, параметр outer_query определяет внешний запрос, который использует OTB для получения всех вызовов объединения обеих членов.
Для демонстрации рекурсивной формы OTB мы используем таблицу Airplane, определенную и заполненную кодом, показанным в примере ниже:
USE SampleDb;
CREATE TABLE Airplane (ContainingAssembly VARCHAR(10),
ContainedAssembly VARCHAR(10),
QuantityContained INT,
UnitCost DECIMAL (6,2));
INSERT INTO Airplane VALUES ("Самолет", "Фюзеляж",1, 10);
INSERT INTO Airplane VALUES ("Самолет", "Крылья", 1, 11);
INSERT INTO Airplane VALUES ("Самолет", "Хвост",1, 12);
INSERT INTO Airplane VALUES ("Фюзеляж", "Салон", 1, 13);
INSERT INTO Airplane VALUES ("Фюзеляж", "Кабина", 1, 14);
INSERT INTO Airplane VALUES ("Фюзеляж", "Нос",1, 15);
INSERT INTO Airplane VALUES ("Салон", NULL, 1,13);
INSERT INTO Airplane VALUES ("Кабина", NULL, 1, 14);
INSERT INTO Airplane VALUES ("Нос", NULL, 1, 15);
INSERT INTO Airplane VALUES ("Крылья", NULL,2, 11);
INSERT INTO Airplane VALUES ("Хвост", NULL, 1, 12);
Таблица Airplane состоит из четырех столбцов. Столбец ContainingAssembly определяет сборку, а столбец ContainedAssembly - части (одна за другой), которые составляют соответствующую сборку. На рисунке ниже приведена графическая иллюстрация возможного вида самолета и его составляющих частей:
Таблица Airplane состоит из следующих 11 строк:
В примере ниже показано применение предложения WITH для определения запроса, который вычисляет общую стоимость каждой сборки:
USE SampleDb;
WITH list_of_parts(assembly1, quantity, cost) AS
(SELECT ContainingAssembly, QuantityContained, UnitCost
FROM Airplane
WHERE ContainedAssembly IS NULL
UNION ALL
SELECT a.ContainingAssembly, a.QuantityContained,
CAST(l.quantity * l.cost AS DECIMAL(6,2))
FROM list_of_parts l, Airplane a
WHERE l.assembly1 = a.ContainedAssembly)
SELECT assembly1 "Деталь", quantity "Кол-во", cost "Цена"
FROM list_of_parts;
Предложение WITH определяет список OTB с именем list_of_parts, состоящий из трех столбцов: assembly1, quantity и cost. Первая инструкция SELECT в примере вызывается только один раз, чтобы сохранить результаты первого шага процесса рекурсии. Инструкция SELECT в последней строке примера отображает следующий результат.