loading..
Русский    English
06:00
листать

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

Заметим, что в общем случае запрос возвращает множество значений. Поэтому использование подзапроса в предложении 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
365,818181818182

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

Тэги:
ALL AVG battles CASE CAST CHAR CHARINDEX classes COALESCE Convert COUNT CTE DATEDIFF DATEPART DATETIME DELETE DISTINCT EXCEPT EXISTS EXTRACT FROM FULL JOIN GROUP BY Guadalcanal HAVING IN INNER JOIN insert INTERSECT ISNULL laptop LEFT LEFT OUTER JOIN LEN maker MAX MIN MySQL NOT IN NULL ORDER BY Outcome outcomes OVER PARTITION BY pc PIVOT PostgreSQL printer product Больше тэгов
Учебник обновлялся
несколько дней назад
©SQL-EX,2008 [Развитие] [Связь] [О проекте] [Ссылки] [Team]
Перепечатка материалов сайта возможна только с разрешения автора.
Rambler's Top100