Оператор SELECT .

Весь запрос SELECT разбивается на отдельные разделы, каждый из которых имеет своё назначение. Большая часть этих разделов может быть опущена. Упрощённый вариант синтаксиса оператора SELECT :

1 SELECT [ALL | DISTINCT] < список вывода >

2 [ INTO <имя новой таблицы> ]

3 FROM <список таблиц и условий соединения>

4 [ WHERE <условие отбора или соединения> ]

5 [ GROUP BY <список полей группировки> ]

6 [ HAVING <условия, накладываемые на группу> ]

7 [ ORDER BY <список полей для сортировки вывода> ]

8 [ UNION <запрос на выборку для объединения>]

9 …

 

<список вывода>::=

{ * |

[<имя таблицы> | <алиас>.] {<имя столбца> | <выражение>} [ AS <алиас>] |

<имя столбца> = <выражение>

} [… n ]

Символ звёздочка означает, что в результирующий набор включаются все столбцы из указанных исходных таблиц:

SELECT * FROM publishers

Декартово произведение отношений:

SELECT * FROM publishers, authors

ALL – в результирующий набор включаются все строки, удовлетворяющие условиям запроса, даже если среди них будут одинаковые (?!, то есть полученное отношение не удовлетворяет требованиям реляционной алгебры).

SELECT ALL p.country FROM publishers AS p

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

SELECT DISTINCT state, contract FROM authors

Простейшие вычисления в разделе SELECT:

SELECT ' Название книги : ', title, yearpub-1992 FROM titles WHERE yearpub > 1992;

Раздел WHERE предназначен для наложения горизонтальных фильтров на данные, обрабатываемые запросом. Для этого указывается логическое условие, от результата вычисления которого зависит, будет ли строка включена в результат выборки или нет.

SELECT au_lname, au_fname, state FROM authors WHERE state<>'CA'

Предикаты, используемые в условных конструкциях SQL :

1) Предикаты сравнения: = , <> , < , > , >= , <= ;

SELECT * FROM authors WHERE 1=1

2) AND – соединение нескольких логических выражений;

SELECT title FROM titles WHERE yearpub>=1995 AND yearpub<=1997

3) OR – если одно из двух условий истинно, то результат True ;

SELECT title FROM titles WHERE yearpub<1995 OR yearpub>1997

4) NOT – отрицание, может ставиться непосредственно перед нижеследующими предикатами;

5) Предикат диапазона: Between A and B – принимает значение True , если сравниваемое значение лежит между A и В;

SELECT title FROM titles WHERE yearpub NOT BETWEEN 1995 AND 1997

6) Вхождение во множество: IN (<список значений>) – принимает True , если сравниваемое значение входит во множество заданных значений;

SELECT title FROM titles WHERE yearpub IN (1995, 1996, 1997)

7) Сравнение с образцом: LIKE . В шаблон могут входить специальные символы « _ » – для обозначения любого одиночного символа, и « % » – для обозначения произвольной последовательности символов;

SELECT publisher, url FROM publishers WHERE publisher LIKE ‘%Wiley%'

8) Предикат сравнения с неопределённым значением: IS NULL .

SELECT publisher, “url not defined !” FROM publishers WHERE url IS NULL

Связь между таблицами с использованием раздела WHERE (стандарт SQL 89)

Представим ситуацию, когда выборку данных надо производить из отношения, которое является результатом слияния нескольких отношений. При отсутствии соединения в разделе WHERE результат будет эквивалентен расширенному декартовому произведению отношений. Обычно всегда в случае использования нескольких таблиц имени поля предшествует имя таблицы во всех разделах оператора SELECT .

SELECT titles.title, titles.yearpub, publishers.publisher

FROM titles, publishers

WHERE titles.pub_id = publishers.pub_id AND titles.yearpub>1996

В данном запросе в разделе WHERE указаны условия связи и условия фильтрации данных.

Связь между таблицами с использованием раздела FROM (стандарт SQL 2, внешние объединения)

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

  1. [INNER] JOIN . Данный тип связи используется по умолчанию. Строки левой таблицы, для которых не имеется пары в правой таблице, в результат выборки не включаются. Строки правой таблицы, для которых не имеется пары в левой таблице, также в результат не включаются.
  2. LEFT [ OUTER ] JOIN . Все строки левой таблицы включаются в результат выборки. При этом, если отсутствуют строки в правой таблице, то в соответствующих столбцах правой таблицы, включенных в результат запроса, будет установлено значение NULL . Строки правой таблицы, для которых не имеется пары в левой таблице, в результат не включаются.
  3. RIGHT [ OUTER ] JOIN . Все строки правой таблицы включаются в результат выборки. Для соответствующих столбцов левой таблицы, включенных в запрос, устанавливается значение NULL . Строки левой таблицы, для которых не имеется пары в левой таблице, в результат не включаются.
  4. FULL [ OUTER ] JOIN . В результат будут включены все строки как левой, так и правой таблицы.
  5. CROSS JOIN – выражение эквивалентно просто запятой между таблицами.

Пример связи двух таблиц:

SELECT authors.au_lname, authors.au_fname, titleauthor.royalty

FROM authors INNER JOIN titleauthor ON authors.au_id = titleauthor.au_id

WHERE authors.state='CA'

Если бы мы хотели узреть и тех авторов из штата Калифорния, которые не получили гонорар, то надо было бы использовать конструкцию LEFT JOIN

Пример связи нескольких таблиц:

SELECT

countries.name_rus AS страна ,

subjects.name_rus AS регион ,

msu.name_rus AS район ,

data.year AS год

FROM

data INNER JOIN

subjects ON data.subject = subjects.subject INNER JOIN

msu ON data.msu = msu.id_msu INNER JOIN

countries ON subjects.country = countries.country

Раздел GROUP BY позволяет выполнять группировку строк таблиц по определённым критериям. Типичным примером использования GROUP BY является суммирование однотипных значений. GROUP BY почти всегда используется вместе с функциями агрегирования. GROUP BY разделяет таблицу на группы, а функция агрегирования вычисляет для каждой из них итоговое значение.

Основные функции агрегирования:

AVG(< поле > )

Среднее значение для указанного столбца или выражения

COUNT(< поле >)

Количество строк, исключая NULL -строки в указанном столбце

COUNT(*)

Общее количество строк, включая NULL -строки

MAX(< поле >)

Максимальное значение в указанном столбце

MIN(< поле >)

Минимальное значение в указанном столбце

SUM(< поле >)

Сумма всех значений в указанном столбце

STDEV(< поле >)

Статистическое стандартное отклонение для значений столбца

VAR(< поле >)

Несмещенная оценка дисперсии величин указанного столбца

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

SELECT publishers.publisher, COUNT(titles.title)

FROM titles, publishers

WHERE titles.pub_id = publishers.pub_id

GROUP BY publisher

Правила использования группировок в запросах:

1) Функции агрегирования не работают со значениями NULL .

2) В разделе SELECT (т.е. для вывода) можно указывать только те поля, по которым осуществляется группировка. Чтобы вывести значения столбцов, не указанных в критериях группировки, необходимо применять к ним функции агрегирования.

3) Раздел WHERE не допускает использования функций агрегирования.

Ещё один пример: подсчитать, сколько записей ввёл каждый из операторов по каждому региону за 2003 год.

SELECT max(subjects.name_rus) as [ субъект ], COUNT(*) AS [ количество записей ],

max(users.u_name) as [ оператор ]

FROM subjects, data, users

WHERE data.subject = subjects.subject and data.id_user = users.id_user and data.year=2003

GROUP BY data.subject, data.id_user

ORDER BY [ субъект ]

Если при выполнении группировки используется раздел WHERE , то возможно появление групп, не содержащих ни одной строки. По умолчанию эти группы не включаются в результат выборки. Однако если необходимо вывести все без исключения группы, то используется вариант GROUP BY ALL . При этом для групп, не содержащих ни одной строки, не выполняются функции агрегирования, вместо которых выводится значение NULL .

Простой запрос, использующий функцию агрегирования без группировки:

SELECT Count(*) FROM data

Раздел HAVING .

Этот раздел практически аналогичен по назначению с разделом WHERE (горизонтальная фильтрация), однако используется для задания условий групповой фильтрации. В этом разделе допускается использование функций агрегирования.

Определим количество книг каждого издательства, исключая случаи единственного экземпляра.

SELECT publishers.publisher, COUNT(titles.title)

FROM titles, publishers

WHERE titles.pub_id = publishers.pub_id

GROUP BY publisher

HAVING COUNT (*)>1;

Другой пример: получить номера деталей, суммарное количество которых на складе превышает 400 шт.

SELECT number, SUM(volume) FROM warehouse

GROUP BY number HAVING SUM(volume)>400

Раздел ORDER BY предназначен для упорядочения набора данных, возвращаемых после выполнения запроса. Используются ключевые слова ASC (по возрастанию, используется по умолчанию) и DESC (по убыванию). При этом в сортировке могут участвовать столбцы, не входящие в раздел SELECT . Приоритет в сортировке по столбцам, указанным первыми.

SELECT data.* FROM data ORDER BY subject, msu, year

Раздел UNION служит для объединения результатов выборки, возвращаемых двумя и более запросами. Это может быть выборка из одной таблицы или слияние данных из множества таблиц. Иными словами, раздел UNION вставляется между двумя запросами, возвращающими одинаковый набор столбцов. В результат будут включены строки как первого, так и второго запроса. По умолчанию дублирующие строки в результат не включаются.

SELECT publisher, url FROM publishers

UNION

SELECT site , url FROM wwwsites

Использование вложенных запросов.

Команда SELECT позволяет использовать подзапросы в предикатах главного (т.е. в разделах WHERE и HAVING ). Совместно с подзапросом можно использовать предикат EXIST , который возвращает истину, если вывод подзапроса не пуст.

Задача: найти названия всех изданий, выпущенные издательством « Wiley »

SELECT title FROM titles WHERE pub_id IN

(SELECT pub_id FROM publishers WHERE publisher='Wiley');

Более сложные задачи: даны отношения

Supplier s ( id _ supplier , name ) – поставщики (код поставщика, ФИО поставщика)

Supply ( id _ supplier , number ) – поставки (код поставщика, номер детали)

Components ( number , title ) – детали (номер детали, наименование детали).

1. Найти имена поставщиков, которые поставляют все детали из занесённых в базу.

SELECT MAX(suppliers.name)

FROM suppliers, supply

WHERE suppliers.id_supplier=supply.id_supplier

GROUP BY supply.id_supplier

HAVING COUNT( DISTINCT supply.number) = (

SELECT COUNT(number) FROM components)

2. Получить список поставщиков, поставляющих деталь с номером 222.

SELECT * FROM suppliers

WHERE EXIST

(SELECT * FROM supply

WHERE suppliers.id_supplier = supply.id_supplier AND supply.number = 222);

Такие подзапросы называются коррелируемыми ( correlated ). Внешняя ссылка может принимать различные значения для каждой строки-кандидата, оцениваемого с помощью подзапроса, поэтому подзапрос должен выполняться заново для каждой строки, отбираемой в основном запросе.

Простой пример: контроль ссылочной целостности вручную:

SELECT * FROM data WHERE item NOT IN (SELECT item FROM items)

Реализация реляционной алгебры средствами оператора SELECT (Реляционная полнота SQL )

Для того, чтобы показать, что язык SQL является реляционно полным, нужно показать, что любой реляционный оператор может быть выражен средствами SQL .

1 . Объединение :

SELECT * FROM A

UNION

SELECT * FROM B

2. Пересечение :

SELECT * FROM A

INTERSECT

SELECT * FROM B

3 . Разность :

SELECT * FROM A

EXCEPT

SELECT * FROM B

4. Декартово произведение:

SELECT A .*, B .* FROM A , B

5. Ограничение :

SELECT * FROM A WHERE С ;

6. Проекция отношения :

SELECT DISTINCT X, Y, Z FROM A

7. Соединение по условию:

SELECT A .*, B .* FROM A , B WHERE С;

8. Деление :

SELECT DISTINCT A.X

FROM A

WHERE NOT EXIST

(SELECT * FROM B

WHERE NOT EXIST

(SELECT * FROM A A1

WHERE A1.X = A.X AND A1.Y = B.Y));

назад главная вперед