loading..
Русский    English
13:21
листать

Еще раз о подзапросах

Заметим, что в общем случае запрос возвращает множество значений. Поэтому использование подзапроса в предложении WHERE без предикатов EXISTS, IN, ALL и ANY, которые дают булево значение, может привести к ошибке времени выполнения запроса.

Пример 5.8.3

Найти модели и цены ПК, стоимость которых превышает минимальную стоимость портативных компьютеров:

Консоль
Выполнить
  1. SELECT DISTINCT model, price
  2. FROM PC
  3. WHERE price > (SELECT MIN(price)
  4. FROM Laptop
  5. );

Этот запрос вполне корректен, так как скалярное значение price сравнивается с подзапросом, который возвращает единственное значение. В результате получим три модели ПК:

model price
1121 850
1233 950
1233 980

Однако, если в ответ на вопрос «найти модели и цены ПК, стоимость которых совпадает со стоимостью портативных компьютеров» написать следующий запрос

Консоль
Выполнить
  1. SELECT DISTINCT model, price
  2. FROM PC
  3. WHERE price = (SELECT price
  4. FROM Laptop
  5. );

то при выполнении последнего мы можем получить такое сообщение об ошибке:

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

(«Подзапрос вернул более одного значения. Это не допускается в тех случаях, когда подзапрос следует после =, !=, <, <=, >, >= или когда подзапрос используется в качестве выражения».)

Эта ошибка будет возникать при сравнении скалярного значения с подзапросом, который возвращает более одного значения.

Подзапросы, в свою очередь, также могут содержать вложенные запросы.

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

Пример 5.8.4

Вывести производителя, тип, модель и частоту процессора для Портативных компьютеров, частота процессора которых превышает 600 МГц.

Этот запрос может быть сформулирован, например, следующим образом:

Консоль
Выполнить
  1. SELECT prod.maker, lap.*
  2. FROM (SELECT 'laptop' AS type, model, speed
  3. FROM laptop
  4. WHERE speed > 600
  5. ) AS lap INNER JOIN
  6. (SELECT maker, model
  7. FROM product
  8. ) AS prod ON lap.model = prod.model;

В результате получим:

maker type model speed
B laptop 1750 750
A laptop 1752 750

Наконец, подзапросы могут присутствовать в предложении SELECT. Это иногда позволяет весьма компактно сформулировать запрос.

Пример 5.8.5

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

Здесь вообще можно обойтись одним предложением SELECT в основном запросе:

Консоль
Выполнить
  1. SELECT (SELECT AVG(price)
  2. FROM Laptop
  3. ) -
  4. (SELECT AVG(price)
  5. FROM PC
  6. ) AS dif_price;

В результате получим

dif_price
328.3333

Рекомендуемые упражнения: 10, 18, 24, 25, 26, 43, 56, 57, 60, 61, 62, 63, 72, 75, 80, 87, 88, 91, 92, 96, 99, 110, 111, 112, 113, 118, 127, 129

Bookmark and Share
Тэги:
ALL AND AUTO_INCREMENT AVG battles CASE CAST CHAR CHARINDEX CHECK classes COALESCE Convert COUNT CROSS APPLY CTE DATEDIFF DATENAME DATEPART DATETIME DDL DEFAULT DELETE DISTINCT DML EXCEPT EXISTS EXTRACT FROM FULL JOIN GROUP BY Guadalcanal HAVING IDENTITY IN INNER JOIN insert INTERSECT IS NOT NULL ISNULL laptop LEFT LEFT OUTER JOIN LEN maker MAX MIN MONTH MySQL NOT Больше тэгов
Учебник обновлялся
вчера
©SQL-EX,2008 [Развитие] [Связь] [О проекте] [Ссылки] [Team]
Перепечатка материалов сайта возможна только с разрешения автора.
Rambler's Top100