Оператор EXISTS
Содержание
Синтаксис SQL 2003
Параметры и ключевые слова следующие
WHERE [NOT] EXISTS
Подзапрос проверяется на наличие одной или нескольких строк. Если хотя бы одна строка удовлетворяет запросу, то возвращается булево значение ИСТИНА. При указании дополнительного ключевого слова NOT булево значение ИСТИНА возвращается, если подзапрос не возвращает соответствующих ему строк.
подзапрос
На основе полностью сформированного подзапроса извлекается результирующий набор данных.
Общие правила
Оператор EXISTS проверяет существование одной или нескольких строк в подзапросе родительского запроса.
В этом примере проверяется в подзапросе записей с помощью дополнительного ключевого слова NOT. В следующем примере для извлечения основного результирующего набора данных производится поиск специфических записей в подзапросе.
Советы и хитрости программирования
Во многих запросах оператор EXISTS выполняет ту же функцию, что и ANY. Оператор EXISTS обычно является наиболее эффективным при использовании с коррелированными запросами.
Оператор EXISTS семантически эквивалентен оператору ANY.
Различия между платформами
Все платформы поддерживают оператор EXISTS в том виде, который мы описали выше.
Дополнительная информация по теме
Правила и методы использования оператора IS в базах данных на различных платформах
Правила и методы использования оператора IN в базах данных на различных платформах
Правила и методы использования оператора LIKE в базах данных на различных платформах
Особенности использования оператора BETWEEN в базах данных, основной синтаксис в выражениях
EXISTS (Transact-SQL)
Specifies a subquery to test for the existence of rows.

Syntax
To view Transact-SQL syntax for SQL Server 2014 and earlier, see Previous versions documentation.
Arguments
subquery
Is a restricted SELECT statement. The INTO keyword is not allowed. For more information, see the information about subqueries in SELECT (Transact-SQL).
Result Types
Boolean
Result Values
Returns TRUE if a subquery contains any rows.
Examples
A. Using NULL in a subquery to still return a result set
B. Comparing queries by using EXISTS and IN
Here is the result set for either query.
C. Comparing queries by using EXISTS and = ANY
D. Comparing queries by using EXISTS and IN
E. Using NOT EXISTS
Here is the result set.
Examples: Azure Synapse Analytics and Analytics Platform System (PDW)
F. Using EXISTS
The following example identifies whether any rows in the ProspectiveBuyer table could be matches to rows in the DimCustomer table. The query will return rows only when both the LastName and BirthDate values in the two tables match.
G. Using NOT EXISTS
NOT EXISTS works as the opposite as EXISTS. The WHERE clause in NOT EXISTS is satisfied if no rows are returned by the subquery. The following example finds rows in the DimCustomer table where the LastName and BirthDate do not match any entries in the ProspectiveBuyers table.
Linux.yaroslavl.ru
Теперь, когда вы уже познакомились с подзапросами, мы можем поговорить о некоторых специальных операторах, которые всегда принимают подзапросы как аргументы. Вы узнаете о первом из их в этой главе. Остальные будут описаны в следующей главе.
Оператор EXISTS используется, чтобы указать предикату, производить ли подзапросу вывод или нет. В этой главе вы узнаете, как использовать этот оператор со стандартными и (обычно) соотнесёнными подзапросами. Мы будем также обсуждать специальные вопросы, которые перейдут в игру, когда вы будете использовать этот оператор как относительный агрегат, как пустой указатель NULL и как булев оператор. Кроме того, вы сможете повысить ваш профессиональный уровень относительно подзапросов, исследуя их в более сложных прикладных программах, чем те, которые мы видели до сих пор.
КАК РАБОТАЕТ EXISTS?
EXISTS это оператор, который производит верное или неверное значение, другими словами, булево выражение (см. в Главе 4 обзор этого термина).
Это означает, что он может работать автономно в предикате или в комбинации с другими выражениями, использующими булевы операторы AND, OR и NOT. Он берет подзапрос как аргумент и оценивает его как верный, если тот производит любой вывод, или как неверный, если тот не делает этого. Этим он отличается от других операторов предиката, в которых он не может быть неизвестным.
Например, мы можем решить, извлекать ли нам некоторые данные из таблицы Заказчиков, если, и только если, один или более заказчиков в этой таблице находятся в San Jose (вывод для этого запроса показан на Рисунке 12.1):
Внутренний запрос выбирает все данные для всех заказчиков в San Jose. Оператор EXISTS во внешнем предикате отмечает, что некоторый вывод был произведён подзапросом, и, поскольку выражение EXISTS было полным предикатом, делает предикат верным. Подзапрос (не соотнесённый) был выполнен только один раз для всего внешнего запроса, и, следовательно, имеет одно значение во всех случаях. Поэтому EXISTS, когда используется этим способом, делает предикат верным или неверным для всех строк сразу, что не так уж полезно для извлечения определенной информации.
ВЫБОР СТОЛБЦОВ С ПОМОЩЬЮ EXISTS
В вышеупомянутом примере, EXISTS должен быть установлен так, чтобы легко выбрать один столбец, вместо того чтобы выбирать все столбцы, используя в выборе звёздочку (SELECT *). В этом состоит его отличие от подзапроса, который (как вы видели ранее в Главе 10, мог выбрать только один столбец). Однако в принципе он мало отличается при выборе EXISTS-столбцов или когда выбираются все столбцы, потому что он просто замечает, выполняется или нет вывод из подзапроса, а не использует выведенные значения.
ИСПОЛЬЗОВАНИЕ EXISTS С СООТНЕСЁННЫМИ ПОДЗАПРОСАМИ
В соотнесённом подзапросе предложение EXISTS оценивается отдельно для каждой строки таблицы, имя которой указано во внешнем запросе, точно так же, как и другие операторы предиката, когда вы используете соотнесённый подзапрос. Это даёт возможность использовать EXISTS как верный предикат, который генерирует различные ответы для каждой строки таблицы, указанной в основном запросе. Следовательно, информация из внутреннего запроса будет сохранена, если выведена непосредственно, когда вы используете EXISTS таким способом. Например, мы можем вывести продавцов, которые имеют нескольких заказчиков (вывод для этого запроса показан на Рисунке 12.2):
Для каждой строки-кандидата внешнего запроса (представляющей заказчика, проверяемого в настоящее время) внутренний запрос находит строки, которые совпадают со значением поля snum (которое имел продавец), но не со значением поля cnum (соответствующего другим заказчикам). Если любые такие строки найдены внутренним запросом, это означает, что имеются два разных заказчика, обслуживаемых текущим продавцом (то есть продавцом заказчика в текущей строке-кандидате из внешнего запроса). Предикат EXISTS поэтому верен для текущей строки, и номер продавца поля (snum) таблицы, указанной во внешнем запросе, будет выведен. Если DISTINCT не был указан, каждый из этих продавцов будет выбран один раз для каждого заказчика, которому он назначен.
КОМБИНАЦИЯ ИЗ EXISTS И ОБЪЕДИНЕНИЯ
Однако для нас может быть полезнее вывести больше информации об этих продавцах, а не только их номера. Мы можем сделать это, объединив таблицу Заказчиков с таблицей Продавцов (вывод для запроса показан на Рисунке 12.3):
ИСПОЛЬЗОВАНИЕ NOT EXISTS
Предыдущий пример показал, что EXISTS может работать в комбинации с булевыми операторами. Конечно, самым простым способом (и, вероятно, чаще всего используемым с EXISTS) является оператор NOT. Один из способов, которым мы могли бы найти всех продавцов только с одним заказчиком, будет состоять в том, чтобы инвертировать наш предыдущий пример. (Вывод для этого запроса показан на Рисунке 12.4:)
EXISTS И АГРЕГАТЫ
Попытка использовать агрегаты с EXISTS таким способом, вероятно, покажет, что проблема неверно решалась от начала до конца. Конечно, подзапрос в предикате EXISTS может также использовать один или более из его собственных подзапросов. Они могут иметь любой из различных типов, с которыми мы уже знакомы (или познакомимся далее). Такие подзапросы и любые другие в них позволяют использовать агрегаты, если нет другой причины, по которой они не могут быть использованы. Следующий раздел приводит этому пример. В любом случае вы можете получить тот же самый результат более легко, выбрав поле, которое вы использовали в агрегатной функции, вместо использования самой этой функции. Другими словами, предикат
который был показан выше.
УЛУЧШЕННЫЙ ПРИМЕР ПОДЗАПРОСА
В возможных прикладных программах подзапросы могут становиться многократно вкладываемыми. Вы можете вкладывать их два или более в одиночный запрос, и даже один внутрь другого. Так как можно рассмотреть небольшой блок, чтобы получить всю картину работы этой команды, вы можете воспользоваться способом в SQL, который может принимать различные команды из большинства других языков.
Вот запрос, извлекающий строки всех продавцов, которые имеют заказчиков с более чем одним текущим заказом. Это не обязательно самое простое решение этой проблемы, но оно предназначено для того, чтобы показать улучшенную логику SQL. Вывод этой информации связывает все три наши типовые таблицы:
Вывод для этого запроса показан на Рисунке 12.5.
Мы могли бы разобрать вышеупомянутый запрос примерно так:
Берём каждую строку таблицы Продавцов как строку-кандидат (внешний запрос) и выполняем подзапросы. Для каждой строки-кандидата из внешнего запроса ставим в соответствие каждую строку из таблицы Заказчиков (средний запрос). Если текущая строка заказчиков не совпадает с текущей строкой продавца (т.е. если first.snum second.snum), предикат среднего запроса неправилен. Всякий раз, когда мы находим заказчика в среднем запросе который совпадает с продавцом во внешнем запросе, мы должны рассматривать сам внутренний запрос чтобы определить, будет ли наш средний предикат запроса верен. Внутренний запрос считает число заказов текущего заказчика (из среднего запроса). Если это число больше 1, предикат среднего запроса верен, и строки выбираются. Это делает EXISTS-предикат внешнего запроса верным для текущей строки продавца и означает, что по крайней мере один из текущих заказчиков продавца имеет более чем один заказ.
Если это не кажется достаточно понятным для вас на данной стадии разбора примера, не волнуйтесь. Сложность этого примера хороша, независимо от того, как часто вы будете использовать её в деловой ситуации. Основная цель примеров такого типа состоит в том, чтобы показать вам некоторые возможности, которые могут оказаться в дальнейшем полезными. После работы со сложными ситуациями, подобными этой, простые запросы, которые являются наиболее часто используемыми в SQL, покажутся вам элементарными.
РЕЗЮМЕ
EXISTS, хотя он и кажется простым, может быть одним из самых непонятных операторов SQL. Однако он обладает гибкостью и мощностью. В этой главе овладели большинством возможностей, которые предоставляет EXISTS. В дальнейшем ваше понимание улучшенной логики подзапроса значительно расширится.
Следующим шагом будет овладение тремя другими специальными операторами, которые принимают подзапросы как аргументы: это ANY, ALL и SOME. Как вы увидите в Главе 13, это альтернативные формулировки некоторых возможностей, которые вы уже использовали, но которые иногда могут оказаться предпочтительными.
SQL урок 4. операторы sql Union, Exists; строковые функции
SQL запрос Union (объединение)
Над множеством можно выполнять операции объединения, разности и декартова произведения. Те же операции можно использовать и в sql запросах (выполнять операции с запросами).
Для объединения нескольких запросов используется служебное слово UNION.
Синтаксис:
SQL запрос Union служит для объединения выходных строк каждого запроса в один результирующий набор.
Если используется параметр ALL, то сохраняются все дубликаты выходных строк. Если параметр отсутствует, то в результирующем наборе остаются только уникальные строки.
Объединять вместе можно любое число запросов.
Использование оператора UNION требует выполнения нескольких условий:
Рассмотрим более сложный пример с объединением inner join:
SQL Предикат существования EXISTS
Предикат EXISTS принимает значение TRUE (истина), если подзапрос возвращает хоть какое-нибудь количество строк, иначе EXISTS принимает значение FALSE. Существует также предикат NOT EXISTS, который действует противоположным образом.
Обычно EXISTS используется в зависимых подзапросах (например, IN).
SELECT DISTINCT Производитель FROM product AS pc_product WHERE Тип = «Компьютер» AND EXISTS ( SELECT Производитель FROM product WHERE Тип = «Ноутбук» AND Производитель = pc_product.Производитель )
Ключевые слова SQL SOME | ANY и ALL
Ключевые слова SOME и ANY являются синонимами, поэтому в запросе можно использовать любое из них. Результатом такого запроса будет являться один столбец величин.
| Таблица product: | |
| Таблица pc: | |
SELECT DISTINCT Производитель FROM product WHERE Тип = «Компьютер» AND NOT Номер = ANY( SELECT Номер FROM pc )
SELECT DISTINCT Номер, Цена FROM notebook WHERE Цена > ALL ( SELECT цена FROM pc )

Этот запрос корректен по той причине, что скалярное выражение Цена сравнивается с подзапросом, который возвращает единственное значение
Функции работы со строками в SQL
Функция LEFT вырезает слева из строки заданное вторым аргументом число символов:
Функция RIGHT возвращает заданное число символов справа из строкового выражения:
Функция SQL Replace
Функция заменяет в строке1 все вхождения строки2 на строку3. В первую очередь данная функция полезна в операторах обновления таблиц (Update).
Другие строковые функции SQL
отсекает пробелы в начале строки
отсекает пробелы в конце строки
преобразует все символы строки к нижнему регистру
преобразует все символы строки к верхнему регистру
преобразование числа к его строковому представлению
для добавления указанного количества пробелов
SELECT CONCAT(`name`, SPACE( 6 ), CAST(`zarplata` AS DECIMAL ) ) AS «Сведения» FROM `teachers`
function_exists
(PHP 4, PHP 5, PHP 7, PHP 8)
Описание
Список параметров
Имя функции в виде строки.
Возвращаемые значения
Примеры
Пример #1 Пример использования function_exists()
Примечания
Обратите внимание, что название функции может присутствовать, даже если саму функцию невозможно использовать из-за настроек конфигурации или опций компиляции (например, как для функций image).
Смотрите также
User Contributed Notes 23 notes
You can use this function to conditionally define functions, see: http://php.net/manual/en/functions.user-defined.php
For instance WordPress uses it to make functions «pluggable.» If a plugin has already defined a pluggable function, then the WP code knows not to try to redefine it.
But function_exists() will always return true unless you wrap any later function definition in a conditional clause, like if()<. >. This is a subtle matter in PHP parsing. Some examples:
if ( function_exists ( ‘foo’ )) <
print «foo defined\\n» ;
> else <
print «foo not defined\\n» ;
>
function foo () <>
if ( function_exists ( ‘bar’ )) <
print «bar defined\\n» ;
> else <
print «defining bar\\n» ;
function bar () <>
>
print «calling bar\\n» ;
bar (); // ok to call function conditionally defined earlier
print «calling baz\\n» ;
baz (); // ok to call function unconditionally defined later
function baz () <>
qux (); // NOT ok to call function conditionally defined later
if (! function_exists ( ‘qux’ )) <
function qux () <>
>
?>
Prints:
foo defined
defining bar
calling bar
calling baz
PHP Fatal error: Call to undefined function qux()
Any oddities are probably due to the order in which you include/require files.
It should be noted that the function_exists check is not relative to the root namespace. This means that the namespace should be appended to the check:
PHP supports nested function based on certain criteria.
Please look over the code.
function Audio()
<
echo «Plugged Audo 5.1:
«;
function Volume()
<
echo «Volume controls:
«;
function Equalizer()
<
echo «Equalize Bands:
«;
>
>
>
//Call to nested functions
Audio();
Volume();
Equalizer();
if(function_exists(‘Volume’)):
echo «TRUE»;
else:
echo «FALSE»;
endif;
Case 1: //Result :Works Well
———
Audio();
Volume();
Equalizer();
Case 2: //Results Notice Error. Root function Audio must be called first.
———
Volume();
Case 3: //Results Error. Root function Volume must be called.
———
Audio();
Equalizer();
Note :
The nested function should be called based on their order used.
In our example when Audio is not called and instantly when we try to call Volume puts under error.
Even though there is an possibility to use nested functions in PHP. It looks overhead to do so. Better to avoid in logical ground of script.
Tested on PHP 5.5.32
This is not going to go down as you might expect it should (even if you play smart and require/include_once):
if( function_exists ( ‘my_function’ ))
<
throw new Exception ( «‘my_function’ is already defined!» );
>
function my_function ()
<
// Do the work here
>
?>
This, however does work:
Thought this might save someone a few minutes of debugging time.
function_exists will return false for functions disabled with the disable_functions ini directive. However those functions are still declared so trying to define them yourself will fail.
I would like to comment on the following post:
A note of caution: function_exists() appears to be case-insensitive (at least as of PHP 4.3.8). e.g.:
function MyCasedFunction () <
return true ;
>
// Will return true, even though casing is «wrong»
if ( function_exists ( «mYcAsEdFuNcTiOn» ))
echo «I see it!» ;
?>
I believe that function calls itself are case insensitve, so this function is returning a valid truth. PHP doesn’t care about cases.
Functions within a function are better off as anonymous returns from create_function(), unless you want to be able to call it elsewhere.
However, I have used this in skinning: I use alert_box() to display certain errors, like a faulty SQL query. This simply calls display_alert(), which is defined in my skin scripts. However, alert_box() is sometimes called before I know which skin to load, so it has its own functionality which it uses if function_exists(‘display_alert’) returns false.
If you use suhosin.executor.func.blacklist instead of disabled_functions in your php.ini, function_exists will return true for a disabled function. I used this to have the same beahviour with suhosin.executor.func.blacklist and disabled_functions:
To prevent direct calls to included files i use the following technique.
In the main file create an empty function with a random name. Like so:
function hjudejdjiwe () < return true ; >
?>
Then check for the existence of this function within your include:
if (! function_exists ( ‘hjudejdjiwe’ )) < die( '!' ); >
?>
Simple but effective.
The confusion expressed in some of the submissions here arise because functions declared outside conditional blocks are defined as the code is loaded and are thus callable and exist wherever in the code they are declared, whereas those declared inside a condition block are not defined until that block is executed. Thus:
echo foo();
function foo()
however because those inside a conditional are defined as they are encountered during code execution
yields: Fatal error: Uncaught Error: Call to undefined function foo()
function B () <
function C () <
function D ()<>
>
>
IsFunctionExist ( ‘A’ );
IsFunctionExist ( ‘B’ );
IsFunctionExist ( ‘C’ );
IsFunctionExist ( ‘D’ );
I, too, was wondering whether is_callable or function exists is faster when checking class methods. So, I setup the following test:
class test
<
function test ()
<
return true ;
>
>
is_callable = TRUE, function_exists = FALSE
Did 10000 is_callables in 0.0640790462494 seconds
Did 10000 function_exists in 0.0304429531097 seconds
So the fact that function_exists is twice as fast is slightly over shadowed by the fact that it doesn’t work on class methods, at least not as far as I can tell.
i was wondering whether is_callable or function exists is faster when checking class methods.
my results when doing each operation 10000 times with a simple test class were the following:
is_callable: 0.28671383857727 seconds
function_exists: 0.14569997787476 seconds
(following tests have proved this to be true).
thus you can see, function_exists is twice as fast as is_callable.
This can be used to conditionally define a user function. In this sense, it can act as a sort of inline include_once().
For example, suppose you have a function A that calls function B. B is only used inside function A and is never called from anywhere else in the script. It’s logical (and perfectly legal in PHP) to define B inside of A’s definition, like so:
I stumbled over the same problem as «eddiec» (users not able or not willing to use «_once»-suffixes).
A possible alternative explanation for the behavior:
If a file is included, it is possibly parsed every include-time.(?)
While parsing, every function in global scope is tried to register. THIS gets wrong, when multiple times included, and it produces an error.
If functions are defined within block scopes, their registration seems to be delayed until execution of such a block. Thus, not the function «function_exists» functions wrong, but simply the philosophy of the interpreter produces such results.
Thus, the same effect can be achieved by simply putting block braces around the contents of an include_once file:
if (function_exists(‘function_in_question’)) return;
<
function function_in_question(. )
<
.
>
. other stuff
>
. which is equivalent to.
if (!function_exists(‘function_in_question’))
<
function function_in_question(. )
<
.
>
. other stuff
>
// If you want to chack if the function is enabled or disable in php.ini you can use this function:
function_exists returns false on NULL and empty string:
if ( function_exists ( » )) <
echo «empty string function exists\n» ;
>
if ( function_exists ( NULL )) <
echo «NULL function exists\n» ;
>
?>
Neither of the echo statements happen when I run this.
Note that function_exists will return TRUE in the following situation, presumably because the function «testfunc» was defined when the script was PARSED/ITERPRETED, before the function_exists call was made at RUNTIME:
if ( function_exists ( ‘testfunc’ )) return;
function testfunc () < >
?>
So, this construction is not useful for preventing testfunc from being multiply defined if the script is muliply included or required.
However, the following construction DOES work to prevent multiple defines of testfunc:
if (! function_exists ( ‘testfunc’ )) <
function testfunc () < >
>
?>
CONTRAST this with similar uses of defined() which is completely runtime evaluated. These both work:
function_exists() does not cache its query internally.
by executing the following code
There is a 0.16878 seconds improvement, when you use static array to cache methods existence.
to bob at thethirdshift dot net
regarding is_callable vs function_exists.
using your code
is_callable = TRUE, function_exists = FALSE
Did 10000 is_callables in 0.0443360805511 seconds
Did 10000 function_exists in 0.0111110210419 seconds
then we replace
is_callable(array(‘test’,’test’));
with
$callarray = array(‘test’,’test’); // place this outside for-loop
is_callable($callarray);
is_callable = TRUE, function_exists = FALSE
Did 10000 is_callables in 0.0314660072327 seconds
Did 10000 function_exists in 0.0120670795441 seconds
then we replace
is_callable(array(‘test’,’test’));
with
is_callable(‘test’,’test’);
is_callable = TRUE, function_exists = FALSE
Did 10000 is_callables in 0.00991606712341 seconds
Did 10000 function_exists in 0.0113790035248 seconds
I hope you can see that loop-testing functions is not so simple. 🙂



