Простой оператор SELECT

Оператор SELECT осуществляет выборку из базы данных и имеет наиболее сложную структуру среди всех операторов языка SQL. Практически любой пользователь баз данных в состоянии написать простейший оператор SELECT типа

SELECT * FROM PC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

который осуществляет выборку всех записей из объекта БД табличного типа с именем РС. При этом столбцы и строки результирующего набора не упорядочены. Чтобы упорядочить столбцы результирующего набора, их следует перечислить через запятую в нужном порядке после слова SELECT:

SELECT price, speed, hd, ram, cd, model, code
FROM PC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Ниже приводится результат выполнения этого запроса.

pricespeedhdramCdmodelcode
60050056412x12321
8507501412840x11212
60050056412x12333
8506001412840x11214
850600812840x11215
9507502012850x12336
400500103212x12327
35045086424x12328
350450103224x12329
350500103212x126010
9809004012840x123311

Вертикальную проекцию таблицы РС можно получить, если перечислить только необходимые столбцы. Например, чтобы получить информацию только о частоте процессора и объеме оперативной памяти компьютеров, следует выполнить запрос:

SELECT speed, ram
FROM PC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

который вернет следующие данные:

speedram
50064
750128
50064
600128
600128
750128
50032
45064
45032
50032
900128

Следует отметить, что вертикальная выборка может содержать дубликаты строк в том случае, если она не содержит потенциального ключа, однозначно определяющего запись. В таблице РС потенциальным ключом является поле code. Поскольку это поле отсутствует в запросе, в приведенном выше результирующем наборе имеются дубликаты строк (например, строки 1 и 3). Если требуется получить только уникальные строки (скажем, нас интересуют только различные комбинации скорости процессора и объема памяти, а не характеристики всех имеющихся компьютеров), то можно использовать ключевое слово DISTINCT:

SELECT DISTINCT speed, ram
FROM PC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

что даст следующий результат:

speedram
45032
45064
50032
50064
600128
750128
900128

Помимо DISTINCT может применяться также ключевое слово ALL (все строки), которое принимается по умолчанию.

Чтобы упорядочить строки результирующего набора, можно выполнить сортировку по любому количеству столбцов, указанных в предложении SELECT. Для этого используется предложение ORDER BY список столбцов, являющееся всегда последним предложением в операторе SELECT. При этом в списке столбцов могут указываться как имена столбцов, так и их порядковые позиции в списке предложения SELECT. Так, если требуется упорядочить результирующий набор по объему оперативной памяти в порядке убывания, можно записать:

SELECT DISTINCT speed, ram
FROM PC
ORDER BY ram DESC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

или

SELECT DISTINCT speed, ram
FROM PC
ORDER BY 2 DESC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Результат, приведенный ниже, будет, естественно, одним и тем же.

speedram
600128
750128
900128
45064
50064
45032
50032

Сортировку можно проводить по возрастанию (параметр ASC принимается по умолчанию) или по убыванию (параметр DESC).

Замечание

Не рекомендуется в приложениях использовать запросы с сортировкой по номерам столбцов. Это связано с тем, что со временем структура таблицы может измениться, например, в результате добавления/удаления столбцов. Как следствие, запрос типа

SELECT *
FROM PC
ORDER BY 3;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]
может давать совсем другую последовательность или вообще вызывать ошибку, ссылаясь на отсутствующий столбец.

Сортировка по двум столбцам

SELECT DISTINCT speed, ram
FROM PC
ORDER BY ram DESC, speed DESC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

даст следующий результат:

speedram
900128
750128
600128
50064
45064
50032
45032

Горизонтальную выборку реализует предложение WHERE предикат, которое записывается после предложения FROM. При этом в результирующий набор попадут только те строки из источника записей, для каждой из которых значение предиката равно TRUE. То есть предикат проверяется для каждой записи. Например, запрос «получить информацию о частоте процессора и объеме оперативной памяти для компьютеров с ценой ниже $500» можно сформулировать следующим образом:

SELECT DISTINCT speed, ram
FROM PC
WHERE price < 500
ORDER BY 2 DESC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]
speedRam
45064
45032
50032

В последнем запросе был применен предикат сравнения с использованием операции сравнения «<» (меньше чем). Кроме этой операции сравнения могут использоваться: «=» (равно), «>» (больше), «>=» (больше или равно), «<=» (меньше или равно) и «<>» или «!=» (не равно). Выражения в предикатах сравнения могут содержать константы и любые столбцы из таблиц, перечисленных в предложении FROM. Символьные строки и константы типа дата/время записываются в апострофах.

Примеры простых предикатов сравнения:

предикатописание
price < 1000Цена меньше 1000
type = ‘laptop’Типом продукции является ноутбук
cd = ‘24x’24-скоростной CD-ROM
color <> ’y’Не цветной принтер
ram – 128 > 0Объем оперативной памяти свыше 128 Мбайт
Price <= speed*2Цена не превышает удвоенной частоты процессора

Рекомендуемые упражнения: 1, 2, 3, 4, 5, 6, 9, 14, 31, 33, 42.

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

select model from PC
order by price DESC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Обратите внимание, что сама цена (price) не выводится запросом. Исключением является неоднозначная ситуация, возникающая при исключении дубликатов. Так запрос

select DISTINCT model from PC
order by price DESC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]
уже вызовет ошибку:

ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
(Элементы ORDER BY должны входить в список выбора, если указывается SELECT DISTINCT.)

По той же причине не будет работать запрос с группировкой

select model from PC
group by model
order by price DESC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Column "PC.price" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.
(Столбец “PC.price” недопустим в предложении ORDER BY, так как он не содержится в агрегатной функции или предложении GROUP BY.)

Однако если неоднозначность устранить (выполнить сортировку по какому-либо агрегатному значению для группы), то можно “подправить” запрос:

select model from PC
group by model
order by MAX(price) DESC;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Замечание

Все приведенные здесь запросы (в том числе вызывающие ошибку в SQL Server) будут работать под MySQL, которая сама устраняет неоднозначность. Спросите как? Загляните в документацию MySQL. :-)