Кореллированные и некореллированные вложенные запросы
Вложенные запросы, которые не используют данных внешнего запроса, называются некореллированными. Все приведенные ранее примеры, кроме самого последнего, содержали некореллированные вложенные запросы. Такие вложенные запросы выполняются один раз и их результаты используются во внешнем запросе в качестве констант. Некореллированные вложенные запросы в большинстве случаев не приводят к снижению производительности, если их использовать аккуратно. Совсем иначе дело обстоит с запросами, которые используют данные внешнего запроса. Такие запросы называются кореллированными. Особенность кореллированных запросов состоит в том, что они выполняются для каждой строки внешнего запроса. Это приводит к существенным затратам времени, поэтому в документации к различным СУБД приводятся рекомендации использовать кореллированные запросы только в случае крайней необходимости. Тем не менее, раз такая возможность в языке SQL имеется, пользоваться ею можно, но с предельной осторожностью. В следующих разделах будет приведено несколько примеров кореллированных запросов и показано, как можно решить те же задачи более эффективными способами. Использование ключевых слов ALL и ANY с вложенными запросами Конструкции ALL(SELECT …) и ANY(SELECT…) применяются к вложенным запросам, возвращающим множество строк, употребляются, как правило, во фразах WHERE и HAVING, и означают буквально следующее: all (Select…) – все строки вложенного SELECT any (Select…) – хотя бы одна из строк вложенного SELECT В некоторых случаях употребление этих слов позволяет сформулировать запрос просто и точно. Проиллюстрируем это на примере. Пусть требуется вывести студентов, у которых все оценки – только четверки (никаких других оценок нет). Использование ключевого слова ALL позволяет решить эту задачу «в лоб»:
select cod_st,name_st from students where 4=all(select mark from marks where cod_st=students.cod_st) Если же требуется найти студентов, у которых имеется хотя бы одна четверка, можно прибегнуть к помощи ключевого слова ANY: select cod_st,name_st from students where 4=aNY(select mark from marks where cod_st=students.cod_st) К сожалению, в данных примерах получились кореллированные вложенные запросы, так что прозрачность формулировок запроса идет в ущерб производительности. Можно привести примеры более эффективных запросов, решающих те же самые задачи. Например, чтобы найти студентов, у которых все оценки – четверки, достаточно сообразить, что у таких студентов и минимальная, и максимальная оценки равны 4: select st.cod_st, st.name_st from students st, marks m where st.cod_st= m.cod_st group by m.cod_st having min(m.marks)=4 and max(m.marks)=4 А найти студентов, у которых есть хотя бы одна четверка, можно, например, таким запросом: select DISTINCT st.cod_st, st.name_st from students st, marks m where st.cod_st= m.cod_st AND m.mark=4 Функция EXISTS Эта функция служит для проверки результатов вложенного запроса на пустоту. exists(Select…) возвращает значение «истина», если вложенный SELECT возвращает хотя бы одну строку, и «ложь» в противном случае. Функция NOT EXISTS (SELECT …) противоположна функции EXISTS. Например, пусть требуется вывести всех студентов, у которых нет оценок. selecT cod_st, name_st from students where not exists (select cod_st from marks where cod_st=students.cod_st) Приведенный текст запроса прост для понимания, но есть способы решить ту же задачу более эффективно, используя некореллированный вложенный запрос: select cod_st, name_st from students where cod_st not in (select distinct cod_st from marks) или внешнее соединение таблиц: select st.cod_st, st.name_st from students st left join marks m on st.cod_st=m.cod_st where m.mark is null
Читайте также: Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|