Какой символ ставится в конце предложения sql
Язык SQL (Structured Query Language — структурированный язык запросов) представляет собой стандартный высокоуровневый язык описания данных и манипулирования ими в системах управления базами данных (СУБД), построенных на основе реляционной модели данных [1].
Язык SQL был разработан фирмой IBM в конце 70-х годов. Первый международный стандарт языка был принят международной стандартизирующей организацией ISO в 1989 г. [2], а новый (более полный) — в 1992 г. [3]. В настоящее время все производители реляционных СУБД поддерживают с различной степенью соответствия стандарт SQL92.
- идентифицуруется уникальным именем;
- имеет конечное (как правило, постоянное) ненулевое количество столбцов;
- имеет конечное (возможно, нулевое) число строк;
- столбцы таблицы идентифицируются своими уникальными именами и номерами;
- содержимое всех ячеек столбца принадлежит одному типу данных (т.е. столбцы однородны), содержимым ячейки столбца не может быть таблица;
- строки таблицы не имеют какой-либо упорядоченности и идентифицируются только своим содержимым (т.е. понятие ?номер строки? не определено);
- в общем случае ячейки таблицы могут оставаться ?пустыми? (т.е. не содержать какого-либо значения), такое их состояние обозначается как NULL.
- требования уникальности содержимого каждой ячейки какого-либо столбца и/или совокупности ячеек в строке, относящихся к нескольким столбцам;
- запрета для какого-либо столбца (столбцов) иметь ?пустые? (NULL) ячейки.
- Проекция — построение новой таблицы из исходной путем включения в нее избранных столбцов исходной таблицы.
- Ограничение — построение новой таблицы из исходной путем включения в нее тех строк исходной таблицы, которые отвечают некоторому критерию в виде логического условия (ограничения).
- Объединение — построение новой таблицы из 2-ух или более исходных путем включения в нее всех строк исходных таблиц (при условии, конечно, что они подобны).
- Декартово произведение — построение новой таблицы из 2-ух или более исходных путем включения в нее строк, образованных всеми возможными вариантами конкатенации (слияния) строк исходных таблиц. Количество строк новой таблицы определяется как произведение количеств строк всех исходных таблиц.
Кроме перечисленных выше в языке SQL реализованы операции модификации содержимого строк таблицы и пополнения таблицы новыми строками (что теоретически может рассматриваться как операция объединения), а также операции управления таблицами.
Рассмотренные выше операции над таблицами реляционной БД обладая функциональной полнотой, будучи реализованы на практике в своем ?чистом? каноническом виде, как правило, крайне неэкономичны (в первую очередь это относится к комбинации операций ограничения и декартового произведения). Разработчики реальных реляционных СУБД прибегают ко всевозможным приемам и ?ухищрениям? для минизации вычислительных затрат (в первую очередь, машинного времени) при выполнении этих операций. Общим способом, нашедшим отражение в языке SQL, повышения эффективности выполнения запросов в реляционных СУБД являются импользование ключей индексов.
Индексом называется скрытая от пользователя вспомогательная управляющая структура, обеспечивающая прямой (или ?квази?-прямой) метод доступа к строкам таблицы, позволяющий исключить последовательный просмотр всех строк таблицы для обнаружения отвечающих некоторому критерию поиска. Индексы неявным образом (скрытно от пользователя) автоматически создаются для всех ключей таблицы.
- мощные крупные коммерческие СУБД, ориентированные на хранение огромных объемов информации (от гигабайт);
- мобильные компактные свободно распространяемые (в том числе и в исходных кодах) СУБД, использование которых оправдано и для БД объемом всего лишь в десятки килобайт.
- Sybase SQLserver фирмы Sybase, Inc.;
- Oracle фирмы Oracle Corporation;
- Ingres фирмы Computer Associates International;
- Informix фирмы Informix Corporation.
- PostgreSQL организации PostgreSQL;
- microSQL фирмы Hughes Technologies Pty. Ltd.;
- mySQL фирмы T.C.X DataKonsult AB.
- Интерактивные клиенты, обеспечивающие пользователю-человеку возможность общения с SQL-сервером непосредственно с помощью языка SQL.
- ИПП-клиенты, обеспечивающие интерфейс прикладного программирования (ИПП) прикладным программам, использующим средства SQL-сервера. Такой ИПП может быть средством общения прикладной программы с SQL-сервером на языке SQL или набором стандартных функций доступа к реляционной SQL БД без формирования символьных строк запросов (например, стандартный интерфейс ODBC).
- WWW-клиенты, встраиваемые в World Wide Web-сервера и обеспечивающие доступ к информационным возможностям SQL-сервера пользователям сети Internet по протоколу HTTP (протоколу передачи гипертекстовых документов).
Основы синтаксиса языка SQL
- зарезервированных ключевых слов;
- идентификаторов (имен) таблиц и столбцов таблиц;
- логических, арифметических и строковых выражений, используемых для формирования критериев поиска информации в БД и для вычисления значений ячеек результирующих таблиц;
- идентификаторов (имен) операций и функций, используемых в выражениях.
- один или несколько пробелов,
- один или несколько символов табуляции,
- один или несколько символов ?новая строка?.
- Прописными (большими) буквами (напрмер, SELECT, FROM, WHERE) набраны зарезервированные слова.
- Курсивом (например, имя_табл , сложн_условие ) набраны переменные (нетерминальные символы), подлежащие замене в реальном операторе конструкцией из терминальных символов (идентификаторов, знаков операций, имен функций и т.п.).
- В квадратные скобки (?[. ]?) заключается необязательная часть оператора, которую можно опустить при создании реального оператора (сами квадратные скобки в текст оператора не включаются).
- Вертикальная черта (?|?) означает возможность выбора (?или?) из двух или нескольких вариантов синтаксической конструкции (сама вертикальная черта в текст оператора не включается). Подчеркнутый вариант (например, в ?[ ALL | DISTINCT >?) является умолчательным.
- Последовательность символов ?, . обозначает возможность повторения произвольное количество раз (в том числе и нулевое) предшествующей запятой конструкции. Символ . включается в реальный оператор в качестве разделителя перед каждым повторением конструкции.
- от двойного минуса (?—?) до конца строки;
- от символа ?#? до конца строки;
- между последовательностями ?/*? и ?*/? (стиль комментариев языка СИ).
Учебная база данных
В качестве примера в учебном пособии рассматривается БД, содержащая информацию, используемую для решения двумерной (плоской) задачи анализа напряженно-деформированного состояния механического объекта методом конечных элементов [4].
Метод конечных элементов (МКЭ) — универсальный метод решения краевых задач (систем дифференциальных уравнений в частных производных с краевыми условиями), к которым относится и задача анализа (моделирования) напряженно-деформированного состояния плоских механических объектов. Одним из основных этапов метода является этап разбиения ?тела? моделируемого объекта на элементарные участки, называемые конечными элементами (КЭ). Для плоских объектов чаще всего такие КЭ представляют собой треугольники. Пример покрытия объекта (типа рычага) сеткой конечных элементов представлен ниже. В дальнейшем МКЭ обеспечивает нахождение численных значений фазовых переменных , характеризующих состояние объекта (в нашем случае напряжений поля сил и деформаций), в вершинах таких треугольников, называемых узлами (nodes).
Для идентификации узлов и КЭ их помечают номерами (числами из натурального ряда 1. ). Задача ручного разбиения двумерного (а тем более трехмерного) объекта на КЭ является трудоемкой и нетривиальной, поэтому в реальных промышленных системах анализа, реализующих МКЭ, существует, как правило, несколько автоматических процедур покрытия исследуемой области сеткой КЭ. Однако сгенерированная любым способом (автоматически/вручную/комбинированно) сетка КЭ нуждается в проверке некоторым набором правил ее корректности, обеспечивающих минимальность вычислительных затрат и точность получаемых результатов.
Требуется, например, чтобы форма треугольных КЭ как можно теснее приближалась к равносторонней (это влияет на точность получаемого решения). Для уменьшения вычислительных затрат желательно иметь минимальную разность идентификаторов вершин для каждого КЭ.
В задачах исследования поведения механических объектов под воздействием внешних факторов с каждым КЭ связан набор свойств материала, покрываемого КЭ, в состав которого входят, например, плотность (density) среды, модуль Юнга (elastic module), коэффициент Пуассона (Poisson’s coefficient), прочность (strength) и др.
- произвольно направленная сила;
- произвольно направленный момент сил;
- ?заделка?, жестко фиксирующая положение узла сетки по линейным координатам и углу вращения;
- шарнир, позволяющий узлу свободно ?вращаться? относительно его фиксируемого положения по линейным координатам;
- ?каток?, дающий узлу возможность свободно перемещаться по оси x или y.
- таблица ?nodes?, содержащая информацию об узлах КЭ-сетки (идентификатор, x- и y-координаты);
- таблица ?elements?, содержащая информацию обо всех КЭ, составляющих сетку (номер КЭ, идентификаторы трех вершин, наименование материала);
- таблица ?materials?, содержащая информацию о свойствах различных конструкционных материалов (наименование, плотность, модуль Юнга, коэффициент Пуассона, прочность);
- таблица ?loadings?, содержащая информацию о граничных условиях решаемой задачи (вид условия, его ?направление?, номер узла приложения, числовое значение).
Типы данных языка SQL
- INT[( len )] — целое число длиной 4 байта, представляемое при выводе максимально len цифрами;
- SMALLINT[( len )] — целое число длиной 2 байта, представляемое при выводе максимально len цифрами;
- FLOAT[( len , dec )] — действительное число, представляемое при выводе максимально len символами с dec цифрами после десятичной точки;
- CHAR( size ) — строка символов фиксированной длины размером size символов;
- VARCHAR( size ) — строка символов переменной длины максимальным размером до size символов;
- BLOB (Binary Large OBject) — массив произвольных (двоичных) байтов (максимальный размер зависит от реализации, обычно это 65535 байт); этот тип данных может использоваться, например, для хранения изображений;
- DATE — астрономическая дата;
- TIME — астрономическое время.
- знак числа;
- десятичное число с точкой;
- символ ?е?;
- знак (?+? или ?-?) показателя степени;
- целое число, играющее роль показателя степени числа 10.
Отличие типов данных CHAR и VARCHAR заключается в том, что для хранения в таблице строк символов типа CHAR используется точно size байт (хотя содержание хранимых строк может быть значительно короче), в то время как для строк типа VARCHAR незанятые символами строк (?пустые?) байты в таблице не хранятся.
Подчеркнем, что величины len и dec (в отличие от size ) не влияют на размер хранения данных в таблице, а только форматируют вывод данных из таблицы.
Примечание. Тип данных BLOB поддерживается непосредственно не всеми СУБД, однако каждая из них предлагает его аналог (например, BINARY или IMAGE).
Рекомендация. Разрабатывая мобильное приложение (рассчитанное на работу в среде различных СУБД), старайтесь без необходимости избегать использования необязательных возможностей в описании типов данных.
Манипулирование таблицами
Для создания, изменения и удаления таблиц в SQL БД используются операторы CREATE TABLE, ALTER TABLE и DROP TABLE.
Создание таблицы
Создание таблицы в БД реализуется оператором CREATE TABLE, имеющим следующий синтаксис
CREATE TABLE имя_табл (с_спецификация, . );
- Описание столбца таблицы
имя_столбца тип_данных [NULL]
имя_столбца тип_данных NOT NULL [DEFAULT по_умолч] [PRIMARY KEY]
PRIMARY KEY имя_ключа (имя_столбца, . )
KEY имя_ключа (имя_столбца, . )
Примеры
Ниже приводятся примеры использования оператора CREATE TABLE для создания четырех таблиц учебной БД.
CREATE TABLE nodes (
id SMALLINT NOT NULL PRIMARY KEY, # номер узла
x FLOAT NOT NULL, # x-координата
y FLOAT NOT NULL); # y-координата
CREATE TABLE elements (
id SMALLINT NOT NULL PRIMARY KEY, # номер КЭ
n1 SMALLINT NOT NULL, # номер первой вершины
n2 SMALLINT NOT NULL, # номер второй вершины
n3 SMALLINT NOT NULL, # номер третьей вершины
props CHAR(12) NOT NULL DEFAULT 'steel');
Столбец props таблицы elements предназначен для хранения названия материала КЭ и не может содержать ?пустых? полей, его значением ?по умолчанию? является строка символов ?steel? (сталь).
CREATE TABLE materials (
name CHAR(12) NOT NULL PRIMARY KEY, # название материала
density FLOAT NOT NULL, # плотность
elastics FLOAT NOT NULL, # модуль Юнга
poisson FLOAT NOT NULL, # к-т Пуассона
strength FLOAT NOT NULL); # прочность
CREATE TABLE loadings (
type CHAR(1) NOT NULL, # тип граничного условия
direction CHAR(1), # направление действия
node SMALLINT NOT NULL, # номер узла приложения
value FLOAT, # числовое значение
KEY key_node (node) ); # вторичный ключ
В таблице граничных условий loadings поля столбцов direction и value могут быть пустыми (иметь значение NULL), поскольку не все виды нагрузок имеют направление действия и/или величину.
Номер узла node приложения граничного условия определяется как ключ поиска в таблице, т.к. типичный запрос на поиск в таблице loadings — это запрос на определение граничных условий для конкретного узла. Однако этот ключ не может быть первичным, поскольку к одному узлу допустимо приложение нескольких граничных условий (например, момент внешних сил в шарнире).
Следует отметить, что в этой таблице первичный ключ может быть сконструирован только составным из столбцов type, direction и node.
Модификация таблицы
Модификация существующей таблицы в БД реализуется оператором ALTER TABLE, имеющим следующий синтаксис
ALTER TABLE имя_табл м_специкация [,м_спецификация . ]
- Добавление нового столбца
ADD COLUMN с_спецификация
DROP PRIMARY KEY
ALTER COLUMN имя_столбца SET по_умолч
ALTER COLUMN имя_столбца DROP DEFAULT
ALTER TABLE materials ADD COLUMN capacity FLOAT NOT NULL, # теплоемкость ADD COLUMN conductivity FLOAT NOT NULL; # теплопроводность
Удаление таблицы
Удаление одной или сразу нескольких таблиц из БД реализуется оператором DROP TABLE, имеющим следующий простой синтаксис
DROP TABLE имя_табл, .
Подчеркнем, что оператор DROP TABLE удаляет не только все содержимое таблицы, но и само описание таблицы из БД. Если требуется удалить только содержимое таблицы, то необходимо использовать оператор DELETE FROM.
Добавление строк в таблицу
- Добавление строки перечислением значений всех ее ячеек
INSERT INTO имя_табл VALUES (знач, . );
INSERT INTO имя_табл (имя_столбца, . ) VALUES (знач, . );
- ячейки, соответствующие столбцам со спецификацией NULL в операторе CREATE TABLE, будут пустыми;
- ячейки, соответствующие столбцам со спецификацией NOT NULL в операторе CREATE TABLE, заполняются значениями ?по умолчанию?.
INSERT INTO имя_табл [(имя_столбца, . )] SELECT .
INSERT INTO nodes VALUES (25, 6.3, 1.8);
Отметим, что добавление новой строки будет удачным только в том случае, если узла с таким же идентификатором в таблице nodes еще нет — дело в том, что столбец id этой таблицы объявлен первичным ключом и, следоваательно, значения всех его ячеек должны быть уникальны.
Пример
Добавление информации о новом КЭ в таблицу elements:
INSERT INTO elements (n1, n2, n3, id) VALUES (14, 25, 18, 46);
В результате в таблице elements появится новая строка, содержащая в поле props значение ?steel?, как умолчательное значение, определенное при создании таблицы.
Пример
Включение в таблицу materials сведений о новом материале:
INSERT INTO materials VALUES ( 'wood', 0.6, 2.0, 0.12, 50);
Пример
Добавление в таблицу граничных условий loadings информации об ориентированном горизонтально ?катке? в узле 2:
INSERT INTO loadings VALUES ( 'r', 'x', 2, NULL);
Выборка данных из таблиц
Для извлечения данных, содержащихся в таблицах SQL БД, используется оператор SELECT, имеющий в общем случае сложный и многовариантный синтаксис. В данном учебном пособии рассматриваются только несложные и наиболее часто используемые примеры конструкций оператора SELECT.
Упрощенно оператор SELECT выглядит следующим образом:
SELECT [ALL | DISTINCT] в_выражение, .
FROM имя_табл [син_табл], .
[WHERE сложн_условие]
[GROUP BY полн_имя_столбца|ном_столбца, . ]
[ORDER BY полн_имя_столбца|ном_столбца [ASC|DESC], . ]
[HAVING сложн_условие];
- количество и смысл (семантика) столбцов определяется списком элементов в_выражение ;
- содержимое строк определяется содержимым исходных таблиц из списка FROM и критерием выборки, задаваемым сложн_условие .
[имя_табл|син_табл.]имя_столбца
Описание столбцов результирующей таблицы
SELECT * FROM materials;
+--------------+---------+----------+---------+----------+ | name | density | elastics | poisson | strength | +--------------+---------+----------+---------+----------+ | steel | 7.80 | 200.00 | 0.25 | 1000.00 | | aluminium | 2.70 | 65.00 | 0.34 | 600.00 | | concrete | 5.60 | 25.00 | 0.12 | 300.00 | | duraluminium | 2.80 | 70.00 | 0.31 | 700.00 | | titanium | 4.50 | 116.00 | 0.32 | 950.00 | | brass | 8.50 | 93.00 | 0.37 | 300.00 | +--------------+---------+----------+---------+----------+
2. Простым (и также часто используемым) случаем в_выражение является полное имя столбца одной из таблиц списка FROM.
Пример
Пусть необходимо определить идентификаторы всех узлов КЭ-сетки, к которым приложено какое-либо граничное условие, при этом необходимо знать тип приложенного условия. Эта задача может быть решена с помощью следующего оператора:
SELECT node, type FROM loadings;
+------+------+ | node | type | +------+------+ | 1 | r | | 2 | r | | 3 | r | | 14 | h | | 27 | f | | 27 | f | +------+------+
Полученная результирующая таблица содержит дублирующие строки для узла 27. Избежать этого можно, добавив в оператор ключевое слово DISTINCT, запрещающее включение в итоговую таблицу одинаковых строк.
SELECT DISTINCT node, type FROM loadings;
+------+------+ | node | type | +------+------+ | 1 | r | | 2 | r | | 3 | r | | 14 | h | | 27 | f | +------+------+
3. В общем случае в_выражение может представлять собой сложное скобочное выражение над содержимым столбцов таблицы, использующее арифметические, строковые, логические операции и функции. Наиболее часто используемые функции описаны ниже в таблицах 1, 2, 3.
Пример
Используемая нами таблица свойств материалов materials содержит в своих столбцах density и elastics значащие разряды чисел, выражающих, соответственно, плотность и модуль Юнга каждого материала. Для получения реальных значений этих свойств в системе единиц измерения СИ (кг/м 3 и Па) необходимо домножить их на масштабные коэффициенты, что реализуется следующим оператором
SELECT name, density*1000, elastics*1e+9 FROM materials;
+--------------+--------------+-----------------+ | name | density*1000 | elastics*1e+9 | +--------------+--------------+-----------------+ | steel | 7800.00 | 200000000000.00 | | aluminium | 2700.00 | 65000000000.00 | | concrete | 5600.00 | 25000000000.00 | | duraluminium | 2800.00 | 70000000000.00 | | titanium | 4500.00 | 116000000000.00 | | brass | 8500.00 | 93000000000.00 | +--------------+--------------+-----------------+
Таблица 1. Арифметические функции
| Синтаксис | Возвращаемое значение |
| ABS( x ) | абсолютное значение x |
| SQRT( x ) | квадратный корень от x |
| MAX( x , y , . ) | значение наибольшего элемента из списка x, y , . |
| MIN( x,y , . ) | значение наименьшего элемента из списка x, y , . |
Таблица 2. Строковые функции
| Синтаксис | Возвращаемое значение |
| LEFT( s,n ) | первые n символов строки s |
| RIGHT( s.n ) | последние n символов строки s |
| SUBSTRING( s, m, n ) | строка, получаемая копированием n символов из строки s , начиная с m -ого символа строки s |
| LCASE( s ) | строка, полученная из s преобразованием всех букв в строчные |
| UCASE( s ) | строка, полученная из s преобразованием всех букв в прописные |
| CONCAT( s1, s2 , . ) | строка, полученная конкатенацией (слиянием) строк s1, s2 , . |
| LENGTH( s ) | длина строки s |
Таблица 3. Операторы и функции, возвращающие логическое значение (1 — ?истина?, 0 — ?ложь?)
| Синтаксис | Возвращаемое значение |
| x = y x ?? y x ? y x ? y x ?= y x ?= y | 1 (?истина?) или 0 (?ложь?) в зависимости от результата операции сравнения (соответственно, ?равно?, ?не равно?, ?больше?, ?меньше?, ?не больше?, ?не меньше?) |
| NOT l | 1, если l= 0 0, если l =1 |
| l1 AND l2 | результат логической операции ?И? над l1 и l2 |
| l1 OR l2 | результат логической операции ?ИЛИ? над l1 и l2 |
| BETWEEN ( x, y z ) | результат выполнения логического выражения ( x ?= y AND x ?= z ) |
| ISNULL ( v ) | 1, если v имеет значение ?пусто? (NULL) 0, в противном случае |
| IFNULL ( v1, v2 ) | v1 , если v1 не ?пусто? v2 , в противном случае |
| s LIKE образец | 1, при удачном сопоставлении строки s с образец 0, в противном случае |
| s NOT LIKE образец | 0, при удачном сопоставлении строки s с образец 1, в противном случае |
образец — константа в виде строки символов, возможно, содержащая метасимволы ?%? и ?_?. В образец метасимвол ?_? сопоставим с любым одиночным символом строки s , метасимвол ?%? — с любой цепочкой символов любой ( в том числе нулевой) длины.
Пример
Пусть необходимо при выводе информации о плотности материалов из таблицы materials идентифицировать материалы, имеющие в своем составе алюминий (правильнее, имеющие в своем названии упоминание об алюминии). Эта задача может быть решена с помощью следующего оператора.
SELECT name, name LIKE '%alu%', density FROM materials;
+--------------+-------------------+---------+ | name | name LIKE '%alu%' | density | +--------------+-------------------+---------+ | steel | 0 | 7.80 | | aluminium | 1 | 2.70 | | concrete | 0 | 5.60 | | duraluminium | 1 | 2.80 | | titanium | 0 | 4.50 | | brass | 0 | 8.50 | +--------------+-------------------+---------+
Пример
Пусть необходимо для каждого конечного элемента определить наибольшее значение разности идентификаторов узлов, являющихся вершинами этого конечного элемента. Данная задача может быть решена следующим оператором
SELECT id, n1, n2, n3, MAX(ABS(n1-n2),ABS(n1-n3),ABS(n2-n3))
FROM elements;
+----+----+----+----+---------------------------------------+ | id | n1 | n2 | n3 | MAX(ABS(n1-n2),ABS(n1-n3),ABS(n2-n3)) | +----+----+----+----+---------------------------------------+ | 29 | 24 | 26 | 25 | 2 | | 30 | 24 | 25 | 23 | 2 | | 31 | 22 | 26 | 24 | 4 | | 1 | 2 | 3 | 5 | &nbs p; 3 | | 2 | 1 | 2 | 4 | &nbs p; 3 | | 3 | 2 | 5 | 4 | &nbs p; 3 | | 4 | 4 | 5 | 6 | &nbs p; 2 | | 25 | 24 | 23 | 21 | 3 | | 20 | 20 | 19 | 17 | 3 | | 21 | 21 | 19 | 20 | 2 | | 22 | 21 | 23 | 19 | 4 | | 12 | 12 | 14 | 13 | 2 | | 13 | 12 | 15 | 14 | 3 | | 14 | 13 | 14 | 18 | 5 | | 26 | 28 | 27 | 22 | 6 | | 7 | 7 | 8 | 9 | &nbs p; 2 | | 8 | 8 | 10 | 9 | 2 | | 9 | 9 | 10 | 11 | 2 | | 10 | 10 | 12 | 11 | 2 | | 11 | 11 | 12 | 13 | 2 | | 16 | 16 | 17 | 14 | 3 | | 17 | 18 | 17 | 14 | 4 | | 18 | 16 | 20 | 17 | 4 | | 19 | 19 | 18 | 17 | 2 | | 15 | 15 | 16 | 14 | 2 | | 27 | 27 | 29 | 26 | 3 | | 28 | 22 | 27 | 26 | 5 | | 5 | 5 | 7 | 6 | &nbs p; 2 | | 6 | 5 | 8 | 7 | &nbs p; 3 | | 23 | 20 | 22 | 21 | 2 | | 24 | 24 | 21 | 22 | 3 | +----+----+----+----+---------------------------------------+
4. В общем случае в_выражение допускает использование агрегативных (называемых также групповыми) функций, принимающих в качестве своего единственного аргумента значения всех ячеек указанного столбца результирующей таблицы. Основные такие функции представлены в таблице 4. Таблица 4. Агрегативные функции
| Синтаксис | Возвращаемое значение |
| SUM( x ) | сумма значений столбца x результирующей таблицы |
| MAX( x ) | наибольшее значение из всех значений ячеек столбца x |
| MIN( x ) | наименьшее значение из всех значений ячеек столбца x |
| AVG( x ) | среднее значение для всех значений ячеек столбца x |
| COUNT( x ) | общее количество ячеек в столбце x |
Пример
Для отыскания наибольшего значения модуля Юнга для материалов, имеющихся в таблице materials, можно использовать следующий оператор
SELECT MAX(elastics) FROM materials;
+---------------+ | MAX(elastics) | +---------------+ | 200.00 | +---------------+
Пример
Следующий оператор SELECT позволяет определить общее количество конечных элементов в КЭ-сетке из нашего примера.
SELECT COUNT(*) FROM elements;
+----------+ | COUNT(*) | +----------+ | 31 | +----------+
Описание критерия выборки содержимого строк результирующей матрицы
В качестве критерия выбора информации из таблиц списка FROM оператора SELECT выступает сложн_условие , записываемое после ключевого слова WHERE и имеющее следующий вид:
прост_условие
прост_условие AND сложн_условие
прост_условие OR сложн_условие
- Сравнение
полн_имя_столбца @ полн_имя_столбца_или_константа
полн_имя_столбца [NOT] LIKE образец
полн_имя_столбца IS [NOT] NULL
Примечание . Обратите внимание, что синтаксис сложн_условие существенно ?беднее? синтаксиса в_выражение . Дело в том, что сложн_условие используется (в том числе и на физическом уровне организации БД) на этапе выборки из исходной (возможно, очень большой) таблицы (таблиц) необходимых строк в результирующую. Для сокращения времени прямого доступа к строкам таблиц они (таблицы) снабжаются ключами и индексами. Реальный эффект от использования ключей и индексов может быть достигнут только при условии, что запросы на поиск в таблицах используют в качестве критерия поиска только значения ячеек столбцов в ?чистом? виде, а не в виде их комбинации в сложном выражении.
Конструкция же в_выражение применяется, по сути дела, к значениям столбцов уже результирующей таблицы, поэтому сложность в_выражение на эффективность выполнения запроса практически никакого влияния не оказывает.
Пример
Для определения координат местоположения узла 11 может использоваться следующий оператор:
SELECT * FROM nodes WHERE >
+----+--------+--------+ | id | x | y | +----+--------+--------+ | 11 | -35.00 | -10.00 | +----+--------+--------+
Пример
Пусть необходимо определить идентификаторы всех конечных элементов, имеющих в качестве одной из своих вершин узел 20. Эта задача может быть решена следующим оператором SELECT
SELECT id FROM elements WHERE n1 = 20 OR n2 = 20 OR n3 = 20;
+----+ | id | +----+ | 20 | | 21 | | 18 | | 23 | +----+
Пример
Для определения идентификаторов узлов КЭ-сетки, расположенных в первом квадранте системы координат можно использовать следующий оператор
SELECT * FROM nodes WHERE x ?= 0 AND y ?= 0;
+----+-------+-------+ | id | x | y | +----+-------+-------+ | 14 | 0.00 | 0.00 | | 15 | 5.00 | 20.00 | | 16 | 20.00 | 8.00 | +----+-------+-------+
Пример
Следующий оператор SELECT может быть использован для определения граничных условий, имеющих в качестве одной из своих характеристик численное значение величины
SELECT * FROM loadings WHERE value IS NOT NULL;
+------+-----------+------+--------+ | type | direction | node | value | +------+-----------+------+--------+ | f | y | 27 | -50.00 | | f | x | 27 | -10.00 | +------+-----------+------+--------+
Упорядочивание и группирование строк результирующей таблицы
- Упорядочение строк достигается перечислением полных имен столбцов, по которым в возрастающем ( ASC ) или убывающем (DESC) порядке сортируются строки результирующей таблицы. При этом строки упорядочиваются в первую очередь по столбцу, указанному первым в списке ORDER BY. Затем, если среди значений ячеек первого столбца есть повторяющиеся, производится упорядочение по второму столбцу и так далее.
Пример
Для вывода информации об узлах КЭ-сетки в убывающем порядке их (узлов) идентификаторов может быть использован следующий оператор:
SELECT * FROM nodes ORDER BY id DESC;
+----+--------+--------+ | id | x | y | +----+--------+--------+ | 29 | 83.00 | -9.00 | | 28 | 65.00 | -5.00 | | 27 | 75.00 | -7.00 | | 26 | 80.00 | -20.00 | | 25 | 75.00 | -35.00 | | 24 | 65.00 | -25.00 | | 23 | 60.00 | -39.00 | | 22 | 60.00 | -15.00 | | 21 | 50.00 | -25.00 | | 20 | 40.00 | -3.00 | | 19 | 30.00 | -27.00 | | 18 | 10.00 | -20.00 | | 17 | 20.00 | -10.00 | | 16 | 20.00 | 8.00 | | 15 | 5.00 | 20.00 | | 14 | 0.00 | 0.00 | | 13 | -15.00 | -14.00 | | 12 | -15.00 | 15.00 | | 11 | -35.00 | -10.00 | | 10 | -40.00 | 15.00 | | 9 | -55.00 | -6.00 | | 8 | -65.00 | 15.00 | | 7 | -75.00 | -3.00 | | 6 | -85.00 | -1.00 | | 5 | -80.00 | 15.00 | | 4 | -95.00 | 10.00 | | 3 | -80.00 | 20.00 | | 2 | -87.50 | 20.00 | | 1 | -95.00 | 20.00 | +----+--------+--------+
- в первую очередь по идентификаторам узлов, являющихся первой вершиной конечного элемента;
- во вторую очередь по идентификаторам узлов, являющихся второй вершиной конечного элемента;
SELECT * FROM elements ORDER BY n1, n2;
+----+----+----+----+-------+ | id | n1 | n2 | n3 | props | +----+----+----+----+-------+ | 2 | 1 | 2 | 4 | steel | | 1 | 2 | 3 | 5 | steel | | 3 | 2 | 5 | 4 | steel | | 4 | 4 | 5 | 6 | steel | | 5 | 5 | 7 | 6 | steel | | 6 | 5 | 8 | 7 | steel | | 7 | 7 | 8 | 9 | steel | | 8 | 8 | 10 | 9 | steel | | 9 | 9 | 10 | 11 | steel | | 10 | 10 | 12 | 11 | steel | | 11 | 11 | 12 | 13 | steel | | 12 | 12 | 14 | 13 | steel | | 13 | 12 | 15 | 14 | steel | | 14 | 13 | 14 | 18 | steel | | 15 | 15 | 16 | 14 | steel | | 16 | 16 | 17 | 14 | steel | | 18 | 16 | 20 | 17 | steel | | 17 | 18 | 17 | 14 | steel | | 19 | 19 | 18 | 17 | steel | | 20 | 20 | 19 | 17 | steel | | 23 | 20 | 22 | 21 | steel | | 21 | 21 | 19 | 20 | steel | | 22 | 21 | 23 | 19 | steel | | 31 | 22 | 26 | 24 | steel | | 28 | 22 | 27 | 26 | steel | | 24 | 24 | 21 | 22 | steel | | 25 | 24 | 23 | 21 | steel | | 30 | 24 | 25 | 23 | steel | | 29 | 24 | 26 | 25 | steel | | 27 | 27 | 29 | 26 | steel | | 26 | 28 | 27 | 22 | steel | +----+----+----+----+-------+
Оператор SELECT выводит значения агрегативных функций для самых ?малых? подгрупп.
Пример
Пусть необходимо определить количество узлов КЭ-сетки, охватываемых каждым видом граничных условий. Для этого может быть использован следующий оператор
SELECT type, COUNT(*) FROM loadings GROUP BY type;
+------+----------+ | type | COUNT(*) | +------+----------+ | f | 2 | | h | 1 | | r | 3 | +------+----------+
Примечание . Конструкция HAVING сложн_условие , как необязательная составная часть предложения GROUP BY, позволяет определять дополнительный (к WHERE сложн_условие ) критерий выборки строк в группы. Этот дополнительный критерий применяется в режиме постпроцессорной обработки к таблице, полученной в результате использования критерия из конструкции WHERE.
Выборка из нескольких таблиц
- построение промежуточной таблицы, представляющей собой декартово произведение таблиц из списка FROM (т.е. таблицы, строки которой представляют собой все возможные сочетания строк исходных таблиц);
- копирование в результирующую таблицу всех строк промежуточной, отвечающих критерию из WHERE сложн_условие (если таковой определен).
SELECT id, elastics FROM elements, materials WHERE AND props = name;
+----+----------+ | id | elastics | +----+----------+ | 25 | 200.00 | +----+----------+
Примечание. Обратите внимание, что в данном примере нигде в операторе SELECT не потребовалось использовать полные имена столбцов различных таблиц. Объясняется это тем, что имена столбцов таблиц elements и materials различны, и поэтому неоднозначностей в именовании быть не может.
Примечание. Хотя концептуальная модель обработки оператора SELECT со списком FROM из двух и более таблиц подразумевает построение декартового произведения этих табллиц, в реальности этого не происходит в силу ?ограниченности? синтаксиса сложн_условие из конструкции WHERE. Так, в нашем последнем примере запрос на выборку осуществлялся в 2 ?коротких? этапа: 1) из таблицы elements (с использованием первичного ключа) прямым доступом извлекается строка с 2) из таблицы materials (опять с использованием первичного ключа) прямым доступом извлекается информация о материале ?steel? (сталь). Очевидно, что такой ?оптимизированный? подход несравненно более эффективен по сравнению с каноническим (через декартово произведение).
Пример
Для вывода координат трех вершин каждого конечного элемента в КЭ-сетке в одной таблице можно использовать следующий оператор
SELECT e.id, node1.x, node1.y, node2.x, node2.y, node3.x, node3.y FROM elements e, nodes node1, nodes node2, nodes node3 WHERE e.n1 = node1.id AND e.n2 = node2.id AND e.n3 = node3.id;
+----+--------+--------+--------+--------+--------+--------+ | id | x | y | x | y | x | y | +----+--------+--------+--------+--------+--------+--------+ | 29 | 65.00 | -25.00 | 80.00 | -20.00 | 75.00 | -35.00 | | 30 | 65.00 | -25.00 | 75.00 | -35.00 | 60.00 | -39.00 | | 31 | 60.00 | -15.00 | 80.00 | -20.00 | 65.00 | -25.00 | | 1 | -87.50 | 20.00 | -80.00 | 20.00 | -80.00 | 15.00 | | 2 | -95.00 | 20.00 | -87.50 | 20.00 | -95.00 | 10.00 | | 3 | -87.50 | 20.00 | -80.00 | 15.00 | -95.00 | 10.00 | | 4 | -95.00 | 10.00 | -80.00 | 15.00 | -85.00 | -1.00 | | 25 | 65.00 | -25.00 | 60.00 | -39.00 | 50.00 | -25.00 | | 20 | 40.00 | -3.00 | 30.00 | -27.00 | 20.00 | -10.00 | | 21 | 50.00 | -25.00 | 30.00 | -27.00 | 40.00 | -3.00 | | 22 | 50.00 | -25.00 | 60.00 | -39.00 | 30.00 | -27.00 | | 12 | -15.00 | 15.00 | 0.00 | 0.00 | -15.00 | -14.00 | | 13 | -15.00 | 15.00 | 5.00 | 20.00 | 0.00 | 0.00 | | 14 | -15.00 | -14.00 | 0.00 | 0.00 | 10.00 | -20.00 | | 26 | 65.00 | -5.00 | 75.00 | -7.00 | 60.00 | -15.00 | | 7 | -75.00 | -3.00 | -65.00 | 15.00 | -55.00 | -6.00 | | 8 | -65.00 | 15.00 | -40.00 | 15.00 | -55.00 | -6.00 | | 9 | -55.00 | -6.00 | -40.00 | 15.00 | -35.00 | -10.00 | | 10 | -40.00 | 15.00 | -15.00 | 15.00 | -35.00 | -10.00 | | 11 | -35.00 | -10.00 | -15.00 | 15.00 | -15.00 | -14.00 | | 16 | 20.00 | 8.00 | 20.00 | -10.00 | 0.00 | 0.00 | | 17 | 10.00 | -20.00 | 20.00 | -10.00 | 0.00 | 0.00 | | 18 | 20.00 | 8.00 | 40.00 | -3.00 | 20.00 | -10.00 | | 19 | 30.00 | -27.00 | 10.00 | -20.00 | 20.00 | -10.00 | | 15 | 5.00 | 20.00 | 20.00 | 8.00 | 0.00 | 0.00 | | 27 | 75.00 | -7.00 | 83.00 | -9.00 | 80.00 | -20.00 | | 28 | 60.00 | -15.00 | 75.00 | -7.00 | 80.00 | -20.00 | | 5 | -80.00 | 15.00 | -75.00 | -3.00 | -85.00 | -1.00 | | 6 | -80.00 | 15.00 | -65.00 | 15.00 | -75.00 | -3.00 | | 23 | 40.00 | -3.00 | 60.00 | -15.00 | 50.00 | -25.00 | | 24 | 65.00 | -25.00 | 50.00 | -25.00 | 60.00 | -15.00 | +----+--------+--------+--------+--------+--------+--------+
Примечание. Обратите внимание, что необходимая для выполнения данного запроса промежуточная таблица в виде декартового произведения (если бы она реально строилась) имеет размер в 31*29*29*29=756059 строк (31 строка в таблице elements и 29 строк в таблице nodes).
Манипулирование строками таблиц
Для удаления и изменения строк таблиц SQL БД применяются операторы DELETE и UPDATE.
Удаление строк
Удаление строк таблицы реализуется оператором DELETE FROM, имеющим следующий синтаксис
DELETE FROM имя_табл [WHERE сложн_условие]
где сложн_условие имеет описанный выше синтаксис. В результате выполнения оператора из таблицы удаляются все строки, удовлетворяющие критерию сложн_условие . Если в операторе DELETE FROM конструкция WHERE опущена, то удаляются все строки таблицы.
Модификация строк
Изменение содержимого строк таблицы реализуется оператором UPDATE, имеющим следующий синтаксис
UPDATE имя_табл SET имя_столбца=выражение, .
[WHERE сложн_условие]
где выражение — выражение (в простейшем случае — константа), согласующееся по результату с типом данных столбца. В выражение допустимо использование значений ячеек любых столбцов таблицы, рассмотренных ранее операций и функций (но не агрегативных), а также прежнего содержимого модифицуруемой ячейки. Обновлению подлежат столбцы строк, отвечающих критерию сложн_условие . Если конструкция WHERE в операторе отсутствует, то обновляются все строки таблицы.
Пример
Для изменения наименования материала, из которого выполнена механическая конструкция, для всех элементов КЭ-сетки можно использовать следующий оператор
UPDATE elements SET props='brass'; SELECT * FROM elements;
+----+----+----+----+-------+ | id | n1 | n2 | n3 | props | +----+----+----+----+-------+ | 29 | 24 | 26 | 25 | brass | | 30 | 24 | 25 | 23 | brass | | 31 | 22 | 26 | 24 | brass | | 1 | 2 | 3 | 5 | brass | | 2 | 1 | 2 | 4 | brass | . . . | 28 | 22 | 27 | 26 | brass | | 5 | 5 | 7 | 6 | brass | | 6 | 5 | 8 | 7 | brass | | 23 | 20 | 22 | 21 | brass | | 24 | 24 | 21 | 22 | brass | +----+----+----+----+-------+
Пример
В нашей КЭ-сетке элемент 22 имеет ?неправильную? форму. Ставится задача заменить его двумя новыми конечными элементами, имеющими форму, более близкую к равносторонней. Эта задача может быть решена следующей последовательностью операторов
DELETE FROM elements WHERE INTO nodes VALUES (30, 45.0, -33.5); INSERT INTO elements VALUES (22, 21, 30, 19); INSERT INTO elements VALUES (32, 21, 23, 30);
Пример
Для решения предыдущей задачи можно также использовать и другой набор операторов
INSERT INTO nodes VALUES (30, 45.0, -33.5); UPDATE elements SET n2 = 30 WHERE INTO elements VALUES (32, 21, 23, 30);
Литература
- Дж. Мартин. Организация баз данных в вычислительных системах. — М.;Мир,1980. — 662с.
- С.Д. Кузнецов. Стандарты языка реляционных баз данных SQL: краткий обзор. //СУБД, 1996, N2, сс. 6-36.
- С.Д. Некузнецов
- Зенкевич О., Морган К. Конечные элементы и аппроксимации. — М.:Мир, 1979. — 318с.
Упражнения
- Определить наилучший материал по показателю ?прочность/плотность?.
- Получить таблицу, содержащую значения наибольших разностей идентификаторов узлов — вершин для каждого конечного элемента.Таблица должна быть упорядочена по убыванию значений разностей.
- Определить максимальное значение в таблице из предыдущего задания.
- Определить протяженность механического объекта вдоль оси x.
- Определить расстояние каждого узла КЭ-сетки до начала системы координат.
- Определить расстояние каждого узла КЭ-сетки до узла, в котором приложено граничное условие в виде горизонтальной силы (подчеркнем, не до узла с заданным идентификатором, а до узла с заданным типом граничного условия).
- Найти наибольшее расстояние между узлами КЭ-сетки.
- Получить таблицу длин сторон всех элементов КЭ-сетки в виде ?идентификатор элемента — длина стороны 1 — длина стороны 2 — длина стороны 3?.
- Получить таблицу расстояний между узлами КЭ-сетки, соединенных сторонами конечных элементов, в виде ?идентификатор узла 1 — идентификатор узла 2 — длина?.
- Получить таблицу площадей всех конечных элементов. Напомним, для вычисления площади треугольника можно использовать формулу
s = SQRT(p*(p-a)*(p-b)*(p-c))
SELECT [ALL|DISTINCT] в_выражение [AS син_столбца], .
FROM . и т.д.
Подстановочные знаки в SQL
В этой статье пойдет разговор о подстановочных символах в структурированном языке запросов SQL (structured query language). Понимание работы соответствующего оператора Like позволит вам выполнять специальные запросы и возвращать (return) искомые значения. Будут рассмотрены примеры для системы управления базами данных MS SQL Server.
Подстановочные знаки необходимы для замены любых символов в строке с последующим сравнением и выборкой нужных данных из таблицы. Они используются при составлении запроса. В декларативном языке программирования SQL для этих целей используется специальный оператор Like. В сочетании с ключевым словом WHERE, Like обеспечивает поиск заданного шаблона в необходимом столбце.
Изучив описание и список (List of wildcards) ниже, вы узнаете, какие подстановочные знаки можно использовать с оператором Like:
- «%» — может замещать собой любые значения (ноль и больше);
- «_» — нижнее подчеркивание означает лишь один символ;
- «[]» — здесь следует любой отдельный символ;
- «^» — тоже любой символ, но не заключенный в скобки;
- «-» — через дефис можно прописать целый набор символов, некий интересующий диапазон.
Выше мы рассмотрели подстановочные знаки для MS SQL Server — СУБД от Microsoft. Однако если сравнить системы SQL Server и Access, мы увидим, что схожим образом обстоит ситуация и в случае с базами данных MS Access — они тоже имеют свою систему подстановочных элементов — вот для сравнения List of wildcards для MS Access:

Также, глядя на вышеуказанные списки, стоит учесть, что все эти элементы можно применять в разнообразных комбинациях.
Однако давайте лучше перейдем к практике: займемся составлением простейших запросов и посмотрим, как Like выполняет возвращение (returning) искомых данных.
Работа Like на примерах MS SQL Server
Для демонстрации работы оператора Like воспользуемся таблицей Customer со следующим содержимым:

Составим инструкцию, которая вернет (returned) из таблицы клиентов (from customers) всех покупателей, имена которых начинаются с буквы «а»:
SELECT * FROM Customer
WHERE FirstName LIKE ‘a%’;
После сравнения и выборки данных клиентов останется всего двое, что соответствует действительности:

Теперь давайте выполним выборку покупателей, в именах которых содержатся буквы «ci». Местонахождение этих букв в слове в нашем случае значения не имеет — главное, чтобы они были:

Мы видим, что оператор Like возвращает (returns) 2 имени. Важно понимать, что не имеет значения, где именно эти символы, ведь % может означать и ноль, то есть указанные символы могут быть и в начале слова, и в середине, и в конце. Чтобы продемонстрировать это, выполним ту же команду, но уже для телефонов. Поместив в шаблон «2», мы увидим, что возвращаются (return) все номера, где встречается цифра 2, причем вне зависимости от места расположения этой двойки:

Теперь поработаем со знаком нижнего подчеркивания. Он означает один и только один любой символ. С его помощью сделаем выборку стран, названия которых заканчиваются на «exico»:

Также учтите, что регистр в составляемом шаблоне значения не имеет, то есть Like сравнивает и возвращает (return) значения без учета регистра:

Теперь немного изменим запрос и задействуем два символа подчеркивания:

После сопоставления данных и отработки запроса мы получим такой же результат.
Дальше — интереснее. Можно выбрать из таблицы все страны, которые начинаются на «S», «F» и «G». Тут пригодятся квадратные скобки и % — то есть мы используем уже комбинацию:

Как видите, все очень даже просто. В следующем предложении выберем уже диапазон значений из нужного столбца, воспользовавшись комбинацией трех подстановочных элементов:

То есть мы вывели все страны, названия которых начинаются с букв A, B или C.
Теперь давайте вспомним, что в программировании существует равно (==) и не равно (!=). По схожей аналогии работает и [charlist]. Если в начале квадратных скобок мы поместим восклицательный знак, произойдет выборка всех данных, которые не отвечают поставленному условию (not). Синтаксис следующий:

Благодаря этому запросу мы получим все города, названия которых НЕ начинаются с букв A, B или C. Но если вернуться к таблицам начала статьи, становится понятно, что это работает лишь для БД MS Access.
Какой символ ставится в конце предложения sql
SQL � Structured Query Language (Структурированный язык запросов). Язык SQL — наиболее распространённый язык управления базами данных типа клиент � сервер. Существует несколько разновидностей SQL. Между ними есть небольшие различия, но основа одна и та же. В Visual Basic 6 возможности языка SQL представлены Microsoft Jet Database ANSI-89. SQL запрос представляет собой набор команд, определённым образом влияющий на отбор данных. Каждая инструкция начинается командой (одной из SELECT, INSERT, DELETE, UPDATE, CREATE, DROP, ALTER, TRANSFORM) и заканчивается точкой с запятой [;].
Команда SELECT — наиболее часто употребляемая команда из всех восьми. Она используется для выборки данных из базы данных. Её синтаксис:
SELECT [Предикат] Поля FROM Таблицы [IN [WHERE . ] [GROUP BY . ] [HAVING . ] [ORDER BY . ];
Необязательные аргументы заключены в [ ].
Предикат — одно из четырёх слов ALL, DISTINCT, DISTINCTROW, TOP. Если предикат не указан, то устанавливается ALL. Предикат ALL позволяет отобрать все записи. При использовании предиката DISTINCT, записи, которые содержат повторяющиеся значения в выбранных в запросе полях, исключаются. Предикат DISTINCTROW исключает из выборки записи, если повторяется вся запись, а не одно из полей. Предикат TOP позволяет отобрать определённое количество записей.
Поля — имена одного или нескольких полей, выборка которых производится. Для выборки всех полей вместо имен полей можно поставить звёздочку [*]. Таблицы — имена одной или нескольких таблиц, из которых производится выборка. База данных — путь и имя внешней базы данных, в которой содержатся таблицы. Если таблицы находятся в текущей базе данных, то этот аргумент необязателен.
Минимальный синтаксис запроса на выборку выглядит так:
SELECT поле FROM Таблица;
Если таблицы, из которых выбираются записи, содержат одноимённые поля, то перед именем поля нужно поставить название таблицы и точку [.].
Предложение WHERE позволяет установить критерии отбора записей. Например :
SELECT * FROM Orders WHERE lang=EN-US style="COLOR: black; mso-ansi-language: EN-US">
В этом запросе происходит выборка всех полей таблицы Orders . Выбираются только те записи, значения поля ID которых равно 5.
Вместо знака равно [=] можно также использовать знаки больше [>] и меньше [
SELECT * FROM Buyers WHERE Age>30;
В этом запросе выбираются все записи из таблицы Buyers , в которых значение поля Age больше 30.
Также возможно использование предложения WHERE вместе с операторами BETWEEN, IN и LIKE. Оператор BETWEEN позволяет отобрать записи, значение определённого поля которых находится в заданном диапазоне. Например:
SELECT * FROM
Здесь выбираются все записи, значение поля ID которых находится между 10 и 20. Оператор IN позволяет отобрать записи, значение поля которых соответствует одному из значений, указанных в скобках.
SELECT * FROM Orders WHERE ID IN ( 10, 12, 30, 45 );
Здесь отбираются все записи, значение поля ID которых соответствует одному из значений 10, 12, 30, 45. Используя предложение WHERE совместно с оператором LIKE, возможен отбор записей, значение одного из полей которых совпадает с маской. Оператор LIKE применим только к текстовым полям. В маске можно использовать следующие символы:
Замещает один любой символ.
Замещает последовательность любого числа символов.
SELECT * FROM Orders WHERE Name LIKE 'Ва_я%'
Здесь выбираются все записи, поле Name которых соответствует маске Ва_я% . Обраатите внимание, что значения текстового типа в SQL-запросах указываются в кавычках.
Предложение GROUP BY позволяет объединять поля в запросе. Предложение ORDER BY позволяет упорядочивать выбираемые записи. При использовании совместно с предложением ключевого слова ASC можно определить возрастающий порядок, а используя DESC, определяется убывающий порядок.
SELECT * FROM Orders ORDER BY Name ASC;
Также можно упорядочивать записи по нескольким полям. Сначала записи упорядочиваются по первому полю, если в нём есть записи, имеющие одинаковые значения, то они упорядочиваются по следующему указанному в предложении ORDER BY полю и т.д. Имена полей пишутся через запятую [,].
SELECT * FROM Orders ORDER BY Name ASC, Email ASC;
Команда UPDATE Команда UPDATE посылает запрос на изменение записи. Синтаксис:
UPDATE Таблица SET
Таблица — имена одной или нескольких таблиц, в которых изменяются записи НовоеЗначение — новые значения для полей записи
Команду UPDATE удобно использовать, если изменяется сразу большое число записей или если изменяемые записи находятся в разных таблицах. Новые значения указываются через запятую для каждого поля. Использование предложения WHERE аналогично его использованию в команде SELECT.
UPDATE Buyers SET Order='Ничего' WHERE lang=EN-US style="COLOR: black; mso-ansi-language: EN-US">
Устанавливаем значение поля покупки ‘Ничего’ у покупателя, номер которого равен 7.
UPDATE Заказы SET
WHERE
Этот запрос немного сложнее. Он повышает сумму заказа на 20% и стоимость доставки на 10% для покупателей из США.
Команда DELETE посылает запрос на удаление записей из таблицы.
DELETE [Таблица.*] FROM Таблица WHERE . ;
Таблица — имя таблицы, из которой удаляются записи.
Использование предложения WHERE аналогично его использованию в команде SELECT.
Аргумент команды DELETE можно не указывать, поскольку он фактически дублируется в предложении FROM.
DELETE FROM Buyers WHERE lang=EN-US style="COLOR: black; mso-ansi-language: EN-US">
Этот запрос удаляет из таблицы Buyers запись, в которой ID равно 8.
Для удаления не всей записи, а только ее поля, следует воспользоваться запросом на изменение записи (команда UPDATE) и поменять значения нужных полей на Null .
Команда INSERT INTO
Команда INSERT INTO предназначена для добавления одной или нескольких записей в конец таблицы. Возможны 2 варианта использования этой команды. Первый вариант добавляет одну запись в таблицу, а второй вариант добавляет записи из одной таблицы в другую. Синтаксис первого варианта:
INSERT INTO
Синтаксис второго варианта:
INSERT INTO
ТаблицаНазначения — таблица, в которую добавляются записи. Поля — названия полей. Таблица — имя таблицы, источника данных. База данных — путь и имя внешней базы данных, в которой содержатся таблицы. Если таблицы находятся в текущей базе данных, то этот аргумент необязателен. Значения — значения полей добавляемой записи.
Все поля записи и соответствующие им значения должны быть определены, иначе им будут присвоены значения Null . Если таблица, в которую добавляются записи, имеет ключевое поле, то в него должны добавляться уникальные, непустые значения. Иначе запись не будет добавлена.
INSERT INTO
VALUES (12, 'Вася
Добавляется новая запись, в которой полям ID, Name , Email , Order соответствуют значения 12, ‘Вася Пупкин ‘, ‘ vasya@pupkin.ru ‘, ‘ Pentium II 450 MHz ‘.
INSERT INTO Orders2001 (ID, Name, Email, Order)
SELECT ID, Name, Email, Order FROM Orders2000;
Этот запрос добавляет все записи из таблицы Orders2000 в таблицу Orders2001.
Команда SELECT . INTO
Команда SELECT . INTO позволяет создать новую таблицу на основе данных из других таблиц. Эта команда используется для архивирования данных, резервного копирования таблиц. Синтаксис команды:
SELECT Поля INTO
Поля — имена одного или нескольких полей, которые будут скопированы в новую таблицу. НоваяТаблица — Имя создаваемой таблицы База данных — путь и имя внешней базы данных, в которой содержатся таблицы. Если таблицы находятся в текущей базе данных, то этот аргумент необязателен. Таблицы — имена таблиц, из которых выбираются записи.
Если имя новой таблицы совпадает с именем уже существующей, то будет сгенерирована ошибка.
SELECT ID, Name, Email, Order INTO
В этой статье я не описал и десятой части всех возможностей языка SQL. С помощью SQL можно создавать и удалять таблицы, соединять таблицы, вставлять в запросы подзапросы и многое другое.
При написании этой статьи использовался Microsoft SQL Server 2000 Developer Edition .
Работаем с SQL – выборка данных

Самым популярным способом доступа к реляционным базам данных является язык запросов SQL. Именно с ним мы и будем знакомиться в этой главе. Мне кажется, проще всего начинать знакомство с доступа к данным, потому что это самый важный и часто используемый компонент и знание, которое необходимо программистам и тестерам.
Для те, кто знает и тем более говорит на английском язык запросов будет прост, потому что построение команд по своей структуре похоже, как мы строим предложения, чтобы попросить голосовой помощник сделать что-то.
Для тестирования нам понадобиться какая-то база данных, на которой мы будем тренироваться. Так как создание самой базы и таблиц я решил отложить на потом, я подготовил файл, который создаст для вас две таблицы.
| Phoneid | Firstname | Lastname | Phone | Cityid |
|---|---|---|---|---|
| 1 | John | Doe | 4144122 | 1 |
| 2 | Steve | Doe | 414124 | 1 |
| 3 | Johnatan | Something | 4142947 | 2 |
| 4 | Donald | Trump | 414251123 | 2 |
| 5 | Alice | Cooper | 414254234 | 2 |
| 6 | Michael | Jackson | 4142544 | 3 |
| 7 | John | Abama | 414254422 | 3 |
| 8 | Andre | Jackson | 414254422 | 3 |
| 9 | Mark | Oh | 414254422 | |
| 10 | Charly | Lownoise | 414254422 |
| Cityid | cityname |
|---|---|
| 1 | Toronto |
| 2 | Vancouver |
| 3 | Montreal |
Итак, скачайте файл testdb.sql
Если вы используете VS Code, то подключитесь к базе данных mysql, откройте новое окно для SQL запросов, скопируйте в него содержимое файла testdb.sql, и нажмите кнопку выполнения.
Если вы используете командную строку, то подключитесь к базе данных, скопируйте содержимое файла testdb.sql в буфер обмена и теперь кликните правой кнопкой в окне терминала. Команды из файла должны вставиться и выполниться в терминале. Выполняться все, кроме последней, вам скорей всего придется нажать Enter, чтобы завершить последнюю команду.
Теперь мы готовы к изучению SQL. Когда вы работаете с Excel таблицей, что вы можете с ней сделать? Искать данные в таблице поиском, добавлять новые строки, изменять существующие, удалять строки. То же самое можно делать и с базой данных, давайте начнем знакомиться с тем, как можно отображать содержимое таблицы и искать данные.
SELECT доступ к одной таблице
Команда SELECT достаточно простая, потому что она выглядит и звучит вполне логично и последовательно. Да, она может быть и сложной, потому что позволяет достаточно многое, и чтобы не пугать вас, я даже не буду пытаться показывать сейчас максимальную версию.
Начнем с самой простой версии:
SELECT колонки FROM базаданных.таблица
Большими буквами я выделил ключевые слова языка запросов SQL, а русскими маленькими буквами показано то, что мы должны заменить на реальные значения. Если перевести эту команду, то она будет звучать:
ВЫБРАТЬ колонки ИЗ база.данных.таблица
Если исправить склонение в последнем слове, то все будет звучать совсем ясно и понятно.
Колонки – это список имен колонок через запятую. Если вы хотите выбрать все колонки, то можно указать символ звездочки *.
У нас есть таблица City, давайте выберем из нее все записи и все колонки. Все колонки, значит нужно заменить слово «колонки» на символ звездочки, а на месте таблицы пишем city и в результате получаем
SELECT * FROM testdb.сity
Не забываем, что если выполнять из командной строки в mysql, то нужно в конце добавить точку запятой, но очень часто она не нужна, поэтому я в своих запросах буду опускать этот символ.
В результате мы должны увидеть следующее:
+--------+-----------+ | cityid | cityname | +--------+-----------+ | 1 | Toronto | | 2 | Vancouver | | 3 | Montreal | +--------+-----------+ 3 rows in set (0.00 sec)
Если мы пишем множество запросов, неужели каждый раз придется писать имя базы данных перед именем таблицы? Нет, это не обязательно. Если вы работаете с определенной базой, то можно как бы перейти в нее, или можно еще сказать выбрать ее. Для этого выполняем команду:
USE базаданных
Слово USE означает «использовать». То есть мы просим сервер использовать определенную базу для всех последующих запросов, пока снова не выберем другую. В нашем случае база данных это testdb, так что выполняем команду:
USE testdb
Теперь имя базы перед именем таблицы указывать не нужно, а значит запрос на получения всех колонок и всех строк из таблицы city может выглядеть теперь так:
SELECT * FROM сity
Это достаточно важный пункт, поэтому не забывайте его. В дальнейшем я буду писать запросы с учетом, что текущая база данных это testdb и поэтому перед именем таблицы указывать имя базы не буду.
В зависимости от настроек и используемой базы данных имена SQL может быть чувствительным к регистру и нет. Все чаще сталкиваюсь с тем, что MySQL по умолчанию ставится чувствительным к регистру, а значит имя таблицы нужно указать именно так, как это было при создании. Чтобы было проще, я все имена давал в нижем регистре.
Это значит, что следующие две команды могут завершиться ошибкой:
SELECT * FROM City SELECT * FROM CITY
Потому что называние города написано в неверном регистре.
Писать команды SQL большими буквами не обязательно. Вот их как раз можно писать в любом регистре и следующая команда завершиться удачно:
select * from city
SeLeCt * FrOm city
Я не помню уже почему, то много лет назад, еще в 90-е годы я привык писать все слова, которые относятся к SQL большими буквами, чтобы они выделялись. На мой взгляд это читается проще, но вы не обязаны следовать этому же подходу.
Если в качестве колонок указать звездочку, то отображаются все поля в том порядке, в котором они создавались в базе данных. Мы можем перечислить имена через запятую:
SELECT cityid, cityname FROM city
В этом случае у нас есть возможность указать имена в любом порядке и указать сначала имя города, а потом идентификатор:
SELECT cityname, cityid FROM city
Или можно отобразить только имя города:
SELECT cityname FROM city
Настоятельно рекомендую повторять все, что мы здесь рассматриваем, потому что именно практика позволяет лучше запомнить материал.
Пробелы в именах объектов базы данных
У тебя может возникнуть вопрос – а что, а можно создавать имена таблица или колонок из нескольких слов и как тогда MySQL будет работать с пробелами? Создавать объекты с пробелами можно, но в этом случае имя нужно окружить специальными символами, которые зависят от базы данных, в MySQL это символ ` который находится слева от цифры 1 на большинстве клавиш.
Так что теоретически наш запрос может выглядеть так:
SELECT `Adress id`, Name FROM `Address Table`
Обратите внимание, что колонка Address id содержит пробел, поэтому вначале и в конце стоит символ `. У колонки Name нет пробелов, поэтому ничего добавлять не нужно. У имени таблицы так же есть пробел.
Если в имени объекта есть пробел, то ` является обязательным, если пробела нет, то можно поставить, а можно и опустить. Это значит, следующие запросы одинаково корректны:
SELECT `cityname` FROM `city`; SELECT cityname FROM `city`; SELECT `cityname` FROM city; SELECT cityname FROM city;
Все они корректны и все будут работать.
Хотя все примеры мы рассматриваем и тестируем под MySQL, почти все они будут работать и в других базах данных, но вот разделитель в разных базах может отличаться. В MS SQL Server это квадратные скобки:
SELECT [cityname] FROM [city];
Очень часто программисты стараются создавать таблицы и колонки без пробелов, поэтому не так часто можно увидеть запросы, в которых используются символы, которыми окружаются имена объектов.
Фильтрация выборки WHERE
Отлично, мы научились выбирать все данные из таблицы или определенные колонки, а теперь хорошо бы научиться еще и выбирать только определенные строки.
Формат команды выборки начинает усложняться и уже начинает выглядеть так:
ВЫБРАТЬ колонки ИЗ таблица ГДЕ фильтр
В качестве фильтра можно указывать имя колонки, по которой мы хотим фильтровать и значение, которое мы ищем. Например, если мы хотим найти все записи из нашего телефонного справочника, где фамилия владельца это Doe, то мы должны в фильтре указать:
lastname = 'Doe'
Здесь lastname – это имя колонки, поэтому его просто указываем без каких-то дополнений. Когда сервер будет читать этот запрос, то он увидит слово lastname, попробует найти это имя среди известных ему имен и без проблем сможет найти его, так что вопросов нет.
Фамилия – это строка, которая неизвестна MySQL. Для него это просто текст, и он не уверен, где начинается строка и заканчивается. Чтобы проще было определить начало и конец произвольных строк, мы должны помещать их в одинарные кавычки, как в примере выше.
Взглянем на следующий пример:
lastname = Mc Donald
Без одинарных кавычек MySQL не сможет понять этот фильтр, потому что он будет думать – нужно ли искать только по Mc или нужно искать по Mc Donald. А если все это объединить в одинарные кавычки, то фильтр станет корректным.
lastname = 'Mc Donald'
Если символы, которыми мы окружаем имена объектов являются НЕ обязательными, то одинарные кавычки являются обязательными и их опускать НЕЛЬЗЯ.
Итак, полный запрос, который все записи людей с фамилией Doe будет выглядеть так:
SELECT * FROM phone WHERE lastname = 'Doe';
В результате вы должны увидеть только две строки:
+---------+-----------+----------+---------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+----------+---------+--------+ | 1 | John | Doe | 4144122 | 1 | | 2 | Steve | Doe | 414124 | 1 | +---------+-----------+----------+---------+--------+ 2 rows in set (0.01 sec)
В большом городе может оказаться слишком много людей с фамилией Doe и когда мы ищем телефон, то скорей всего мы знаем, что нужного нам человека зовут Steve. Мы можем искать сразу по двум колонкам – имени и фамилии, просто объединив обе проверки с помощью слова AND:
SELECT * FROM phone WHERE lastname = 'Doe' AND firstname = 'Steve';
В ответ должна быть отображена только одна строка:
+---------+-----------+----------+--------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+----------+--------+--------+ | 2 | Steve | Doe | 414124 | 1 | +---------+-----------+----------+--------+--------+ 1 row in set (0.00 sec)
Взглянем по-другому – мы ищем по фамилии и хотим увидеть всех, чья фамилия Doe или Jackson. Просто возможно человек поменял фамилию, и мы не знаем, под какой из них остался зарегистрирован телефон. Нам нужна записи, где колонка lastname равна Doe или Jackson. Именно так мы и должны писать наш запрос, объединив две проверки с помощью ИЛИ, в английском это OR:
SELECT * FROM phone WHERE lastname = 'Doe' OR lastname = 'Jackson';
+---------+-----------+----------+-----------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+----------+-----------+--------+ | 1 | John | Doe | 4144122 | 1 | | 2 | Steve | Doe | 414124 | 1 | | 6 | Michael | Jackson | 4142544 | 3 | | 8 | Andre | Jackson | 414254422 | 3 | +---------+-----------+----------+-----------+--------+ 4 rows in set (0.00 sec)
Ok, фамилии меняют после свадьбы и хотя у меня в таблице все имена мужские (я только сейчас сообразил и это сделано не специально), допустим, что мы знаем имя и это Andre. Возможно вы захотите написать запрос так:
SELECT * FROM phone WHERE lastname = 'Doe' OR lastname = 'Jackson' AND firstname = 'Andre';
Может показаться, что в результате должна быть только одна запись – Andre Jackson, но это не так, мы увидим три записи:
+---------+-----------+----------+-----------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+----------+-----------+--------+ | 1 | John | Doe | 4144122 | 1 | | 2 | Steve | Doe | 414124 | 1 | | 8 | Andre | Jackson | 414254422 | 3 | +---------+-----------+----------+-----------+--------+ 3 rows in set (0.00 sec)
Дело в том, что наш запрос говорит, что мы хотим увидеть всех с фамилией Doe ИЛИ всех с фамилией Jackson и именем Andre. Чтобы проще было понять проблему я добавлю скобки, чтобы показать, как сгруппированы проверки:
lastname = 'Doe' OR (lastname = 'Jackson' AND firstname = 'Andre')
Как раз скобки мы и должны использовать, чтобы исправить проблему:
(lastname = 'Doe' OR lastname = 'Jackson') AND firstname = 'Andre'
Здесь мы уже говорим, что у человека может быть фамилия Doe или Jackson, но имя обязательно должно быть Andre.
Вот теперь мы увидим в результате только одну запись:
+---------+-----------+----------+-----------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+----------+-----------+--------+ | 8 | Andre | Jackson | 414254422 | 3 | +---------+-----------+----------+-----------+--------+ 1 row in set (0.00 sec)
Для подобных задач в SQL есть более красивый синтаксис – использовать слово IN, что можно перевести как одно из. Формат такой:
Колонка in (значения, перечисленные через запятую)
То есть запрос, где мы искали одну из двух фамилий, можно переписать так:
SELECT * FROM phone WHERE lastname IN ('Doe', 'Jackson');
На мой взгляд это читается на много проще. Если прочитать это предложение по-русски, то все будет звучать так:
ВЫБРАТЬ все ИЗ телефоны ГДЕ фамилия ОДНА ИЗ ('Doe', 'Jackson')
На мой взгляд наглядно. Если добавить еще и условие с именем, то запрос будет выглядеть так:
SELECT * FROM phone WHERE lastname IN ('Doe', 'Jackson') AND firstname = 'Andre';
Тоже достаточно просто читается и не нужно заморачиваться со скобками, чтобы указать на приоритет, как мы объединяем ИЛИ и И.
Когда мы ищем по числам, то их оборачивать в одинарные кавычки не нужно. Допустим, что мы хотим найти запись в справочнике под номером 1. Именно под номером, а не первую под счету. Такой запрос может выглядеть так:
SELECT * FROM phone WHERE phoneid = 1
В случае с числами еще очень часто может потребоваться искать числа больше или меньше какого-то значения. Допустим, что нужно найти все записи, где id телефона меньше 5. В нашем случае это будет первые 4 строки. Как и в математике, так и в программировании можно использовать символы:
В нашем случае можно использовать < 5 как в следующем примере:
SELECT * FROM phone WHERE phoneid < 5
+---------+-----------+-----------+-----------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+-----------+-----------+--------+ | 1 | John | Doe | 4144122 | 1 | | 2 | Steve | Doe | 414124 | 1 | | 3 | Johnatan | Something | 4142947 | 2 | | 4 | Donald | Trump | 414251123 | 2 | +---------+-----------+-----------+-----------+--------+
Если мы хотим включить в выборку и строку с phoneid равных 5, то можно увеличить число до 6 или использовать меньше или равно
SELECT * FROM phone WHERE phoneid
+---------+-----------+-----------+-----------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+-----------+-----------+--------+ | 1 | John | Doe | 4144122 | 1 | | 2 | Steve | Doe | 414124 | 1 | | 3 | Johnatan | Something | 4142947 | 2 | | 4 | Donald | Trump | 414251123 | 2 | | 5 | Alice | Cooper | 414254234 | 2 | +---------+-----------+-----------+-----------+--------+
Усложняем задачу, ищем записи с id больше 3 и меньше 7. И снова мы можем воспользоваться AND, чтобы объединить две проверки:
SELECT * FROM phone WHERE phoneid > 3 and phoneid < 7
Чтобы проще читать и красивее все выглядело можно то же самое записать:
SELECT * FROM phone WHERE 3 < phoneid and phoneid < 7
Для этой задачи есть вариант решения проще, по крайней мере для некоторых – использовать between:
SELECT * FROM phone WHERE phoneid between 4 and 6;
Обратите внимание, что я использую числа 4 и 6, а не 3 и 7, потому что between включает граничные значение, это то же самое, что и:
SELECT * FROM phone WHERE phoneid >= 4 and phoneid
С точки зрения чтения это звучит лучше: выбрать все из телефонов, где id между 4 и 6. Звучит хорошо, но я почему-то почти не использую эту конструкцию. Мне больше нравится решать то же самое с помощью математических конструкций > или
Если работать со строками, то тут SQL предоставляет нам некую гибкость, мы можем искать по шаблону. Допустим, что мы хотим найти всех, у кого имя начинается с буквы J. Для этого используем новое слово LIKE. В английском это слово очень часто можно перевести как “нравиться” или “выглядеть как”, в зависимости от того, в качестве какой части речи использовать это слово. В данном случае это второй вариант. После этого мы можем использовать в качестве шаблона специальные символы:
% заменяет любое количество любых символов
_ заменяет один, но любой символ
Так как нам нужно найти всех, у кого первая бука J, а потом идет любое количество любых символов, то наш шаблон будет выглядеть как 'J%'
SELECT * FROM phone WHERE firstname LIKE 'J%'
+---------+-----------+-----------+-----------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+-----------+-----------+--------+ | 1 | John | Doe | 4144122 | 1 | | 3 | Johnatan | Something | 4142947 | 2 | | 7 | John | Abama | 414254422 | 3 | +---------+-----------+-----------+-----------+--------+ 3 rows in set (0.00 sec)
А что если мы хотим найти любую фамилию, в которой содержится хотя бы одна буква A. Для этого можно указать % перед и после буквы A:
SELECT * FROM phone WHERE lastname LIKE '%a%'
Символ % означает любое количество любых символов, значит до и после A может быть что угодно и в любом количестве.
Отлично, но что, если мы не знаем только одну букву. Например, моя фамилия Флёнов, но очень часто приходиться писать Фленов только потому, что буква ё не поддерживается. Очень часто это проблема печати – в паспорте, в бумажном журнале или в книге.
SELECT * FROM phone WHERE lastname LIKE 'Фл_нов’
Подчеркивание означает один и только один символ. Недостаток именно этого запроса – он возвращает не только Фленов и Флёнов, но, возможно, и какие-то другие вариации, если они существуют Фланов, Флонов и т.д. Но возможно именно это нам и нужно.
Пустые поля NULL
Если выбрать все содержимое таблицы phone, то в последних двух строках будет не число, а какое странное NULL:
SELECT * FROM phone;
+---------+-----------+-----------+-----------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+-----------+-----------+--------+ | 1 | John | Doe | 4144122 | 1 | | 2 | Steve | Doe | 414124 | 1 | | 3 | Johnatan | Something | 4142947 | 2 | | 4 | Donald | Trump | 414251123 | 2 | | 5 | Alice | Cooper | 414254234 | 2 | | 6 | Michael | Jackson | 4142544 | 3 | | 7 | John | Abama | 414254422 | 3 | | 8 | Andre | Jackson | 414254422 | 3 | | 9 | Mark | Oh | 414254422 | NULL | | 10 | Charly | Lownoise | 414254422 | NULL | +---------+-----------+-----------+-----------+--------+
NULL – это не строка и не число, это отсутствующее значение, то есть в этих двух строках в колонке cityid отсутствует. NULL можно перевести как ноль, но правильнее все же переводить это слово как “несуществующий” или “недействительный”.
Если поле с числом равно 0, то это число, просто оно нулевое. А если поле с числом равно NULL, то это уже не число и не ноль, это значит, что там вообще числа нет, черная дыра, пробоина, все что угодно, но только не число.
Я только что ляпнул новое понятие – поле. Это пересечение колонки и строки. Это то, куда мы записываем значение какой-то колонки/строки.
Особенно такие вещи могут путать в случае работы со строками. Некоторые программы для работы с запросами отображают пустую строку и отсутствующее значение как просто пустоту. Но это не так. Просто в обоих случаях отобразить нечего.
Для базы данных есть огромная разница – мы храним пустую строку или в поле нет вовсе значения, потому что это разные вещи. Если строка пустая, то это все же строка, просто у нее нет длины, но если значения нет, то строки не существует.
Скорость у машины может быть нулевая, если машина стоит или какое-то число, если машина едет. А если машины нет? Скорости тоже не будет в принципе, и мы не можем сказать, что скорость нулевая у машины, которой просто нет.
Работа с нулевыми полями отличается, потому что если попробовать выполнить запрос:
select * from phone where cityid = null;
то ничего не вернется. Казалось бы, мы же сравниваем число символом сравнения с NULL, но это не работает. Дело в том, что сравнивать с помощью равенства нельзя, вместо этого нужно использовать слово is:
select * from phone where cityid is null;
А если мы хотим найти все строки, в которых поле не пустое, а имеет какое-то значение. Тут нужно использовать is not:
select * from phone where cityid is not null;
На этом пока с основами получения данных закончим. В процессе рассмотрения дальнейшего материала мы познакомимся с еще более сложными запросами на практике.
Сортировка данных в запросах SQL
Когда мы выполняем запрос, то база данных может вернуть данные в любой последовательности, хотя чаще всего возвращает строки в том порядке, в котором они хранятся и чаще всего это будет совпадать со значением ключевой колонки, в нашем случае это phoneid.
Если вы хотите отсортировать по фамилии, то мы должны это явно сказать серверу. Для этого используется ORDER BY, который ставиться в конце запроса:
select * from phone order by lastname;
+---------+-----------+-----------+-----------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+-----------+-----------+--------+ | 7 | John | Abama | 414254422 | 3 | | 5 | Alice | Cooper | 414254234 | 2 | | 1 | John | Doe | 4144122 | 1 | | 2 | Steve | Doe | 414124 | 1 | | 6 | Michael | Jackson | 4142544 | 3 | | 8 | Andre | Jackson | 414254422 | 3 | | 10 | Charly | Lownoise | 414254422 | NULL | | 9 | Mark | Oh | 414254422 | NULL | | 3 | Johnatan | Something | 4142947 | 2 | | 4 | Donald | Trump | 414251123 | 2 | +---------+-----------+-----------+-----------+--------+
Обратите внимание, что первая колонка теперь не отсортирована, а вот в lastname все значения возрастают начиная с буквы A в сторону Z. Нет, это происходит не всегда. Если мы не указали направление сортировки, то используется ASC, возрастание, то есть это то же самое, что написать:
select * from phone order by lastname asc;
А теперь посмотрите на колонку имени – оно не по возрастающей. Мы попросили отсортировать по фамилии, а когда фамилия одинаковая, то сервер имеет право вернуть данные в любом порядке и в данном случае ему удобно вывести в соответствии с ключевой колонкой phoneid. У Michael Jackson первая колонка равна 6 и это меньше 8, что мы видим у Andre.
Если вы хотите, чтобы в случае одинаковой фамилии данные сортировались по имени, то нужно указать обе колонки именно в таком порядке:
select * from phone order by lastname asc, firstname asc;
следующий запрос вернет то же самое, потому что не забываем, что ASC – возрастание это сортировка по умолчанию:
select * from phone order by lastname, firstname;
Теперь данные будут сначала отсортированы по фамилии и если фамилия одинакова, то по имени и в обоих случаях по возрастающей.
Можно сортировать по любому количеству колонок, если это реально принесет выгоду.
Если вы хотите отсортировать таблицу по фамилии, но в обратном порядке, то вместо ASC нужно указать DESC – убывание:
select * from phone order by lastname desc;
+---------+-----------+-----------+-----------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+-----------+-----------+--------+ | 4 | Donald | Trump | 414251123 | 2 | | 3 | Johnatan | Something | 4142947 | 2 | | 9 | Mark | Oh | 414254422 | NULL | | 10 | Charly | Lownoise | 414254422 | NULL | | 6 | Michael | Jackson | 4142544 | 3 | | 8 | Andre | Jackson | 414254422 | 3 | | 1 | John | Doe | 4144122 | 1 | | 2 | Steve | Doe | 414124 | 1 | | 5 | Alice | Cooper | 414254234 | 2 | | 7 | John | Abama | 414254422 | 3 | +---------+-----------+-----------+-----------+--------+
Добавить запись в таблицу
Мы разобрались с базовыми возможностями выборки данных и сегодня давайте посмотрим, как можно добавлять новые данные. Самый простой формат вставки данных в базу данных наверно
INSERT имя таблицы VALUES (значения колонок)
С именем таблицы вопросов нет. Если мы хотим вставить значения в таблицу телефонов, то пишем:
INSERT phone VALUES (значения колонок)
При такой команде в скобках нужно обязательно указать значения для каждой колонки. Строковые значения должны быть в одинарных кавычках, числовые могут быть в кавычках, но лучше все же без них. Это уже более глубокий вопрос, который мы скорей всего рассмотрим чуть позже.
Мы пока типы полей не рассматривали, но в некоторые колонки вставлять данные нельзя. К таким относится ключевое поле, если оно настроено как авто увеличиваемое. Некоторые базы позволяют изменять даже автоматически увеличиваемые поля, но даже в этом случае это не очень хорошо.
MySQL относится как раз к тем базам, которые могут позволить вставлять даже в автоматические поля, хотя повторюсь, я это не рекомендую. Первое поле в обеих таблицах, которые я создал для примеров этой работы как раз является автоматически увеличиваемым и ключом. Об этом подробнее во время создания таблиц, а сейчас просто для общего развития такой небольшой отступ от основной темы.
Итак, мы должны перечислить значения всех колонок, а их у нас в таблице 5, из которых первое и последние числа, значит их указываем без кавычек и указываем именно число. Первое поле ключ и его значение указывать не обязательно, но если вы сделаете это, то обязательно укажите уникальное число, которого до сих пор не было. Я создал таблицу с 10 строками, и первая колонка содержит значения от 1 до 10. Следующее значение 11, поэтому можно указать его.
Итак, запрос на вставку записи с ID равным 11 будет выглядеть так:
INSERT phone VALUES (11, 'Anna', 'Koko', '41213213', 1);
Как я уже сказал, я сделал первую колонку автоматически увеличиваемой, поэтому значение для нее указывать не обязательно. Если вы не хотите самостоятельно искать следующее свободное число, просто не указывайте его, а вместо числа можно использовать NULL, как мы помним это как бы отсутствующее значение:
INSERT phone VALUES (null, 'Elen', 'Rokoko', '41213183', 1);
Если мы показываем, что для первой колонки передано NULL, то есть мы не хотим указывать значение, то для автоматически увеличиваемых полей сервер сам найдет следующее свободное и будет использовать его. В нашем случае должно быть 12. Проверим:
mysql> select * from phone;
+---------+-----------+-----------+-----------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+-----------+-----------+--------+ | 1 | John | Doe | 4144122 | 1 | | 2 | Steve | Doe | 414124 | 1 | | 3 | Johnatan | Something | 4142947 | 2 | | 4 | Donald | Trump | 414251123 | 2 | | 5 | Alice | Cooper | 414254234 | 2 | | 6 | Michael | Jackson | 4142544 | 3 | | 7 | John | Abama | 414254422 | 3 | | 8 | Andre | Jackson | 414254422 | 3 | | 9 | Mark | Oh | 414254422 | NULL | | 10 | Charly | Lownoise | 414254422 | NULL | | 11 | Anna | Koko | 41213213 | 1 | | 12 | Elen | Rokoko | 41213183 | 1 | +---------+-----------+-----------+-----------+--------+ 12 rows in set (0.00 sec)
Поля таблиц могут быть настроены так, что они будут обязательными и нет. Я для этого примера намеренно сделал все поля необязательными, а значит мы можем просто передать вместо значений для каждой колонки только NULL:
INSERT phone VALUES (null, null, null, null, null);
SELECT * FROM phone WHERE phoneid = 13;
И вот что, что мы получили
+---------+-----------+----------+-------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+----------+-------+--------+ | 13 | NULL | NULL | NULL | NULL | +---------+-----------+----------+-------+--------+ 1 row in set (0.04 sec)
Указывать отсутствующее значение (NULL) для всех колонок, для которых мы не хотим указывать реальное значение – странно и глупо. Вместо этого после имени таблицы в скобках можно указать имена колонок, значения которых мы хотим указать:
INSERT phone (phoneid, phone, firstname) VALUES (14, '4184719', 'Mary');
В этом запросе после имени таблицы в скобках указаны имена колонок phoneid, phone и firstname. Я намеренно указал имена не в том порядке, как они созданы в таблице, ведь реально имя находиться в таблице вторым, а здесь третьим.
Именно в таком же порядке должны быть предоставлены значения в круглых скобках после слова VALUES. Как видите значения тоже идут в таком же порядке – ID, номер телефона и только потом имя.
Таким образом мы можем опускать любые необязательные поля, но только необязательные. Если колонка обязательно должна иметь значение, то мы обязаны указать ее в операторе INSERT и предоставить значение.
У нас необязательных значений нет, так что теоретически мы можем выполнить такую команду:
INSERT phone () VALUES ();
Будет вставлена новая строка, у которой будут заданы только колонки, для которых есть значения по умолчанию или автоматически увеличиваемые. Эта команда идентична уже той, что мы выполняли:
INSERT phone VALUES (null, null, null, null, null);
Она выполниться успешно только если в таблице нет колонок с обязательными полями без значения по умолчанию.
SQL - Обновление данных
Бывают такие случаи, когда данные вставил в таблицу и они больше никогда не меняются. Но в реальной жизни нередко данные подвержены изменениям и у нас должна быть возможность сделать это.
Минимальная команда изменения данных:
UPDATE таблица SET колонка1 = значение, колонка2 = значение . . . WHERE фильтр
В секции WHERE мы можем писать такие же условия, как мы делали и при SELECT. В остальном в принципе все понятно.
Давайте посмотрим на содержимое строки с >
SELECT * FROM phone WHERE phoneid = 14;
+---------+-----------+----------+---------+--------+ | phoneid | firstname | lastname | phone | cityid | +---------+-----------+----------+---------+--------+ | 14 | Mary | NULL | 4184719 | NULL | +---------+-----------+----------+---------+--------+ 1 row in set (0.00 sec)
Здесь у нас Мэри, но у нее не было указано фамилии. Давайте обновим эту строку и укажим фамилию.
UPDATE phone SET lastname = 'Poppins' WHERE
Стоп, что указать в качестве фильтра WHERE? Можно указать имя, но если в базе данных будет несколько записей людей с именем Mary, то мы обновим их все. Не думаю, что мы этого хотим.
По номеру телефона. . . Возможно это сработает, если номер действительно уникальный.
Если у нас есть колонка с уникальными значениями, то лучше использовать ее, тогда мы точно будем знать, что обновлена именно нужная нам запись. Именно поэтому создают в базах данных ключевые поля, как я это сделал с phoneid и самый простой способ добиться уникальности – сделать колонку автоматически увеличиваемой или сохранять в ней что-то типа уникального GUID.
Некоторые базы данных даже не позволяют обновлять данные в таблице, если в ней нет уникальной колонки, потому что база данных в таком случае не может гарантировать, что будет обновлена или удалена именно нужная колонка.
Если забыть про наличие phoneid, которую я заведомо и продуманно создал, то мы можем вставить в таблицу две записи с абсолютно одинаковыми значениями. Допустим, что у нас есть такая таблица:
+-----------+-----------+-----------+ | firstname | lastname | cityid | +-----------+-----------+-----------+ | Mary | NULL | 4184719 | | Mary | NULL | 4184719 | | NULL | NULL | NULL | +-----------+-----------+-----------+
Как мы можем обновить вторую запись Mary, без уникального кода id? А первую? Да все равно какую из них! Записи идентичны и с обновлением проблема. Самый простой способ – удалить обе записи и вставить новые. Да, это решит проблему, но все же.
Именно поэтому некоторые не разрешают изменять данные, если нет первичного ключа, который гарантирует уникальность данных, потому что хотя бы этот ключ и будет различать записи.
С другой стороны, при наличии первичного уникального ключа, которым является personid, желательно использовать его:
UPDATE phone SET lastname = 'Poppins' WHERE personid = 14
Если ты потерялся и все еще не понимаешь, что такое первичный ключ, мы еще будем говорить на тему ключей, когда будем создавать таблицы. Я помню мне тоже на первом этапе знакомства с базами данных было не совсем понятно было что это такое, зачем это нужно. Пока просто помните, что первичный ключ, это колонка (может и не одна), которая гарантирует уникальность каждой строки.
Мы можем обновлять не одну, а сразу несколько колонок, указав их значения через запятую. Давайте изменим сразу фамилию и телефон:
UPDATE phone SET lastname = 'Poppins', phone = '48171738' WHERE personid = 14
Удаление данных из базы данных
Самая простая тема – это удаление данных. Самый простой вариант удалить данные – выполнить оператор:
DELETE FROM имятаблицы
Что удалиться? Все!
Если мы не хотим удалять все, то мы можем добавить уже знакомую нам секцию WHERE:
DELETE FROM phone WHERE firstname = 'Mary'
Здесь мы удаляем все записи, где телефон принадлежит человеку с именем Mary. Если их больше одного, то будут удалены все.
Если нужно удалить только конкретную запись, то мы снова можем использовать первичный ключ:
DELETE FROM phone WHERE phoneid = 14
В этом примере мы удалим запись, где id телефона равен 14.