Простой оператор SELECT
Оператор SELECT осуществляет выборку из базы данных и имеет наиболее сложную структуру среди всех операторов языка SQL. Практически любой пользователь баз данных в состоянии написать простейший оператор SELECT типа
SELECT * FROM PC;
[[ column ]] |
---|
[[ value ]] |
который осуществляет выборку всех записей из объекта БД табличного типа с именем РС. При этом столбцы и строки результирующего набора не упорядочены. Чтобы упорядочить столбцы результирующего набора, их следует перечислить через запятую в нужном порядке после слова SELECT:
SELECT price, speed, hd, ram, cd, model, code
FROM PC;
[[ column ]] |
---|
[[ value ]] |
Ниже приводится результат выполнения этого запроса.
price | speed | hd | ram | Cd | model | code |
---|---|---|---|---|---|---|
600 | 500 | 5 | 64 | 12x | 1232 | 1 |
850 | 750 | 14 | 128 | 40x | 1121 | 2 |
600 | 500 | 5 | 64 | 12x | 1233 | 3 |
850 | 600 | 14 | 128 | 40x | 1121 | 4 |
850 | 600 | 8 | 128 | 40x | 1121 | 5 |
950 | 750 | 20 | 128 | 50x | 1233 | 6 |
400 | 500 | 10 | 32 | 12x | 1232 | 7 |
350 | 450 | 8 | 64 | 24x | 1232 | 8 |
350 | 450 | 10 | 32 | 24x | 1232 | 9 |
350 | 500 | 10 | 32 | 12x | 1260 | 10 |
980 | 900 | 40 | 128 | 40x | 1233 | 11 |
Вертикальную проекцию таблицы РС можно получить, если перечислить только необходимые столбцы. Например, чтобы получить информацию только о частоте процессора и объеме оперативной памяти компьютеров, следует выполнить запрос:
SELECT speed, ram
FROM PC;
[[ column ]] |
---|
[[ value ]] |
который вернет следующие данные:
speed | ram |
---|---|
500 | 64 |
750 | 128 |
500 | 64 |
600 | 128 |
600 | 128 |
750 | 128 |
500 | 32 |
450 | 64 |
450 | 32 |
500 | 32 |
900 | 128 |
Следует отметить, что вертикальная выборка может содержать дубликаты строк в том случае, если она не содержит потенциального ключа, однозначно определяющего запись. В таблице РС потенциальным ключом является поле code. Поскольку это поле отсутствует в запросе, в приведенном выше результирующем наборе имеются дубликаты строк (например, строки 1 и 3). Если требуется получить только уникальные строки (скажем, нас интересуют только различные комбинации скорости процессора и объема памяти, а не характеристики всех имеющихся компьютеров), то можно использовать ключевое слово DISTINCT:
SELECT DISTINCT speed, ram
FROM PC;
[[ column ]] |
---|
[[ value ]] |
что даст следующий результат:
speed | ram |
---|---|
450 | 32 |
450 | 64 |
500 | 32 |
500 | 64 |
600 | 128 |
750 | 128 |
900 | 128 |
Помимо DISTINCT может применяться также ключевое слово ALL (все строки), которое принимается по умолчанию.
Чтобы упорядочить строки результирующего набора, можно выполнить сортировку по любому количеству столбцов, указанных в предложении SELECT. Для этого используется предложение ORDER BY список столбцов, являющееся всегда последним предложением в операторе SELECT. При этом в списке столбцов могут указываться как имена столбцов, так и их порядковые позиции в списке предложения SELECT. Так, если требуется упорядочить результирующий набор по объему оперативной памяти в порядке убывания, можно записать:
SELECT DISTINCT speed, ram
FROM PC
ORDER BY ram DESC;
[[ column ]] |
---|
[[ value ]] |
или
SELECT DISTINCT speed, ram
FROM PC
ORDER BY 2 DESC;
[[ column ]] |
---|
[[ value ]] |
Результат, приведенный ниже, будет, естественно, одним и тем же.
speed | ram |
---|---|
600 | 128 |
750 | 128 |
900 | 128 |
450 | 64 |
500 | 64 |
450 | 32 |
500 | 32 |
Сортировку можно проводить по возрастанию (параметр ASC принимается по умолчанию) или по убыванию (параметр DESC).
Замечание
Не рекомендуется в приложениях использовать запросы с сортировкой по номерам столбцов. Это связано с тем, что со временем структура таблицы может измениться, например, в результате добавления/удаления столбцов. Как следствие, запрос типа
SELECT *
FROM PC
ORDER BY 3;
[[ column ]] |
---|
[[ value ]] |
Сортировка по двум столбцам
SELECT DISTINCT speed, ram
FROM PC
ORDER BY ram DESC, speed DESC;
[[ column ]] |
---|
[[ value ]] |
даст следующий результат:
speed | ram |
---|---|
900 | 128 |
750 | 128 |
600 | 128 |
500 | 64 |
450 | 64 |
500 | 32 |
450 | 32 |
Горизонтальную выборку реализует предложение WHERE предикат, которое записывается после предложения FROM. При этом в результирующий набор попадут только те строки из источника записей, для каждой из которых значение предиката равно TRUE. То есть предикат проверяется для каждой записи. Например, запрос «получить информацию о частоте процессора и объеме оперативной памяти для компьютеров с ценой ниже $500» можно сформулировать следующим образом:
SELECT DISTINCT speed, ram
FROM PC
WHERE price < 500
ORDER BY 2 DESC;
[[ column ]] |
---|
[[ value ]] |
speed | Ram |
---|---|
450 | 64 |
450 | 32 |
500 | 32 |
В последнем запросе был применен предикат сравнения с использованием операции сравнения «<» (меньше чем). Кроме этой операции сравнения могут использоваться: «=» (равно), «>» (больше), «>=» (больше или равно), «<=» (меньше или равно) и «<>» или «!=» (не равно). Выражения в предикатах сравнения могут содержать константы и любые столбцы из таблиц, перечисленных в предложении 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;
[[ column ]] |
---|
[[ value ]] |
Обратите внимание, что сама цена (price) не выводится запросом. Исключением является неоднозначная ситуация, возникающая при исключении дубликатов. Так запрос
select DISTINCT model from PC
order by price DESC;
[[ column ]] |
---|
[[ value ]] |
По той же причине не будет работать запрос с группировкой
select model from PC
group by model
order by price DESC;
[[ column ]] |
---|
[[ value ]] |
Однако если неоднозначность устранить (выполнить сортировку по какому-либо агрегатному значению для группы), то можно “подправить” запрос:
select model from PC
group by model
order by MAX(price) DESC;
[[ column ]] |
---|
[[ value ]] |
Замечание
Все приведенные здесь запросы (в том числе вызывающие ошибку в SQL Server) будут работать под MySQL, которая сама устраняет неоднозначность. Спросите как? Загляните в документацию MySQL. :-)