|
Программирование >> Построение запросов sql
Рис. 3.104. Результат использования связанного подзапроса с предикатом SINGULAR Если использовать в предыдущем запросе предикат NOT SINGULAR, то будут выведены абоненты, у которых имеется более одной ремонтной заявки или вообще нет заявок: SELECT * FROM Abonent A WHERE NOT SINGULAR (SELECT RequestCD FROM Request R WHERE A.AccountCD=R.AccountCD);. Результат выполнения запроса представлен на рис. 3.105.
Рис. 3.105. Результат использования подзапроса с NOT SINGULAR 3.3.2.6. Предикат EXISTS Условие EXISTS означает проверку существования. В SQL условие поиска с проверкой существования представляется следующим выражением: [NOT] EXISTS (<табличный подзапрос>). Результат условия считается истинным только тогда, когда результат выполнения <табличный подзапрос> является непустым множеством, т.е. когда существует какая-либо запись в таблице, указанной в предложении FROM запроса, удовлетворяющая условию поиска предложения WHERE вложенного запроса. Другими словами, EXISTS - это предикат, который возвращает значение, равное TRUE или FALSE, в зависимости от наличия вывода из вложенного запроса. Он может работать автономно в условии поиска или в комбинации с другими логическими выражениями, использующими логические операции AND, OR и NOT. Он берет вложенный запрос как аргумент и оценивает его: - как верный, если тот производит любой вывод; - как неверный, если тот не делает этого. Этим он отличается от других предикатов в условии поиска, где он не может быть неизвестным. Например, существует возможность с помощью следующего запроса решить, извлекать ли некоторые данные из таблицы Abonent, если хотя бы у одного из абонентов имеются непогашенные заявки на ремонт газового оборудования: SELECT AccountCD, Fio FROM Abonent WHERE EXISTS (SELECT * FROM Request WHERE Executed = 0);. Результат выполнения запроса представлен на рис. 3.106.
Рис. 3.106. Результат использования условия EXISTS В этом примере вложенный запрос выбирает все данные о непогашенных ремонтных заявках. Предикат EXISTS в условии поиска внешнего запроса отмечает , что вложенным запросом был произведен некоторый вывод, и, поскольку предикат EXISTS был одним в условии поиска, делает условие поиска основного запроса верным. Поскольку в таблице заявок имеются (EXISTS) строки Executed = 0, то в ТРЗ представлены все строки таблицы Abonent. В соотнесенном вложенном запросе предикат EXISTS оценивается отдельно для каждой строки таблицы, имя которой указано во внешнем запросе, т. е. алгоритм выполнения запроса с предикатом EXISTS и связанным подзапросом точно такой же, как и для всех запросов с соотнесенными подзапросами в условии поиска. Например, можно с помощью следующего запроса вывести коды неисправностей, которые возникали у газового оборудования нескольких абонентов: SELECT DISTINCT FailureCD FROM Request Out WHERE EXISTS (SELECT * FROM Request Inn WHERE Inn.FailureCD = Out.FailureCD AND Inn.AccountCD <> Out.AccountCD);. FAILURECD Рис. 3.107. Результат использования условия EXISTS при соотнесенном вложенном запросе Для каждой строки-кандидата внешнего запроса внутренний запрос находит строки, совпадающие со значением в поле FailureCD и соответствующие разным абонентам (условие AND Inn. AccountCD <> Out. AccountCD ). Если любые такие строки найдены внутренним запросом, то это означает, что имеются два разных абонента, газовое оборудование которых имело текущую неисправность (то есть неисправность в текущей строке-кандидате из внешнего запроса). Предикат EXISTS возвращает TRUE для текущей строки (т.к. результат выполнения подзапроса является непустым множеством), и номер неисправности из таблицы, указанной во внешнем запросе, будет выведен. Если DISTINCT не указывать, то каждая из этих неисправностей будет выбираться для каждого абонента, у которого она произошла (у некоторых несколько раз). Использование NOT EXISTS указывает на инверсию результатов запроса. Как предикат, EXISTS можно использовать во всех случаях, когда необходимо определить, имеется ли вывод из вложенного запроса. Поэтому можно использовать предикат EXISTS и в соединении таблиц. Например, с помощью следующего запроса можно вывести не только коды, но и названия неисправностей, которые возникали у газового оборудования нескольких абонентов: SELECT DISTINCT D.FailureCD, D.FailureNM FROM Disrepair D, Request Out WHERE EXISTS (SELECT * FROM Request Inn WHERE Inn.FailureCD = Out.FailureCD AND Inn.AccountCD <> Out.AccountCD) AND D.FailureCD = Out. FailureCD;. В этом примере внешний запрос - это соединение таблицы Disrepair с таблицей Request. Результат выполнения запроса представлен на рис. 3.108.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |