SELECT DISTINCT model, price
FROM PC
WHERE price
(SELECT MIN(price)
FROM Laptop);
Этот запрос вполне корректен, т.к. скалярное значение price сравнивается с подзапросом, который возвращает единственное значение. В результате получим три модели ПК:
model | price |
---|---|
1121 | 850.0 |
1233 | 950.0 |
1233 | 980.0 |
Однако, если в ответ на вопрос "найти модели и цены ПК, стоимость которых совпадает со стоимостью ПК-блокнота" написать следующий запрос:
SELECT DISTINCT model, price
FROM PC
WHERE price =
(SELECT price
FROM Laptop);
то при выполнении последнего мы можем получить такое сообщение об ошибке:
Эта ошибка будет возникать при сравнении скалярного значения с подзапросом, который либо возвращает более одного значения, либо ни одного.
Подзапросы, в свою очередь, также могут содержать вложенные запросы.
С другой стороны, подзапрос, возвращающий множество строк и содержащий несколько столбцов, вполне естественно может использоваться в предложении FROM. Это позволяет ограничить набор столбцов и/или строк при выполнении операции соединения таблиц.
Этот запрос может быть сформулирован, например, следующим образом:
SELECT prod.maker, lap.*
FROM (SELECT 'Laptop' AS type, model, speed
FROM Laptop
WHERE speed 600) AS lap INNER JOIN
(SELECT maker, model
FROM Product) AS prod ON lap.model = prod.model;
В результате получим:
maker | type | model | speed |
---|---|---|---|
B | Laptop | 1750 | 750 |
A | Laptop | 1752 | 750 |
Наконец, подзапросы могут присутствовать в предложении SELECT. Это иногда позволяет весьма компактно сформулировать запрос.
Здесь вообще можно обойтись одним предложением SELECT:
SELECT (SELECT AVG(price)
FROM Laptop) -
(SELECT AVG(price)
FROM PC) AS dif_price;
В результате получим:
dif_price |
---|
365.81818181818187 |
Преобразование типов
В реализациях языка SQL может быть выполнено неявное преобразование типов. Так, например, в T-SQL при сравнении или комбинировании значений типов smallint и int, данные типа smallint неявно преобразуются к типу int. Подробно о явном и неявном преобразовании типов в MS SQL Server можно прочитать в BOL.
Попытка выполнить запрос
SELECT 'Средняя цена = ' + AVG(price) FROM laptop;
приведет к сообщению об ошибке
Это сообщение означает, что система не может выполнить неявное преобразование типа varchar к типу money. В подобных ситуациях может помочь явное преобразование типов. При этом, как указано в сообщении об ошибке, можно воспользоваться функцией CONVERT. Однако эта функция не стандартизована, поэтому в целях переносимости рекомендуется использовать стандартное выражение CAST. С него и начнем.
Если переписать наш запрос в виде
SELECT 'Средняя цена = ' + CAST(AVG(price) AS CHAR(15)) FROM laptop;
в результате получим то, что требовалось:
Средняя цена = 1410.44 |
Мы использовали выражение явного преобразования типов CAST для приведения среднего значения цены к строковому представлению. Синтаксис выражения CAST очень простой:
CAST( AS )
При этом следует иметь в виду, во-первых, что не любые преобразования типов возможны (стандарт содержит таблицу допустимых преобразований типов данных). Во-вторых, результат функции CAST для значения выражения, равного NULL, тоже будет NULL.
Рассмотрим еще один
SELECT AVG(launched) FROM ships;