Maison > base de données > tutoriel mysql > Utilisation de EXISTS dans SQL

Utilisation de EXISTS dans SQL

jacklove
Libérer: 2018-06-14 16:54:55
original
2846 Les gens l'ont consulté

Par exemple, il existe une requête dans la base de données Northwind telle que
SELECT c.CustomerId,CompanyName FROM Customers c
WHERE EXISTS(
SELECT OrderID FROM Orders o WHERE o.CustomerID=c.CustomerID)
Comment fonctionne EXISTS ici ? La sous-requête renvoie le champ OrderId, mais la requête externe recherche les champs CustomerID et CompanyName. Ces deux champs ne sont certainement pas dans OrderID. Comment correspondent-ils ?
EXISTS est utilisé pour vérifier si la sous-requête renverra au moins une ligne de données. La sous-requête ne renvoie réellement aucune donnée, mais renvoie True ou False
EXISTS spécifie une sous-requête pour détecter l'existence de lignes.
Syntaxe : sous-requête EXISTS
Paramètres : la sous-requête est une instruction SELECT restreinte (la clause COMPUTE et le mot-clé INTO ne sont pas autorisés).
Type de résultat : Booléen Renvoie VRAI si la sous-requête contient des lignes, FLASE sinon.

Exemple de tableau A : TableIn Exemple de tableau B : TableEx

例表A:TableIn 例表B:TableEx


(1). L'utilisation de NULL dans la sous-requête renvoie toujours l'ensemble de résultats

select * from TableIn where exists(select null)
等同于: select * from TableIn
Copier après la connexion



(2) Comparez en utilisant EXISTS et IN. requête. Notez que les deux requêtes renvoient les mêmes résultats.

select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)
select * from TableIn where ANAME in(select BNAME from TableEx)
Copier après la connexion



(3) Comparez les requêtes en utilisant EXISTS et = ANY. Notez que les deux requêtes renvoient les mêmes résultats.

select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)
select * from TableIn where ANAME=ANY(select BNAME from TableEx)
Copier après la connexion



NOT EXISTS fait exactement le contraire d'EXISTS. Si la sous-requête ne renvoie aucune ligne, la clause WHERE dans NOT EXISTS est satisfaite.

Conclusion :
La valeur de retour de la clause EXISTS (y compris NOT EXISTS) est une valeur BOOL. Il existe une instruction de sous-requête (SELECT ... FROM...) dans EXISTS, que j'appelle l'instruction de requête interne d'EXIST. L'instruction de requête qu'il contient renvoie un ensemble de résultats. La clause EXISTS renvoie une valeur booléenne selon que le jeu de résultats de l'instruction de requête qu'elle contient est vide ou non vide.

Une façon courante de le comprendre est la suivante : remplacez chaque ligne de la table de requête externe par la requête interne en tant que test. Si le résultat renvoyé par la requête interne est une valeur non nulle, la clause EXISTS renvoie TRUE. .Cette ligne peut être la ligne de résultat de la requête externe, sinon elle ne peut pas être utilisée comme résultat.

L'analyseur examinera d'abord le premier mot de l'instruction. Lorsqu'il constatera que le premier mot est le mot-clé SELECT, il passera au mot-clé FROM, puis trouvera le nom de la table via le mot-clé FROM et le mettra. La table est chargée en mémoire. L'étape suivante consiste à rechercher le mot-clé WHERE. S'il ne peut pas être trouvé, il reviendra à SELECT pour trouver l'analyse du champ. Si WHERE est trouvé, il analysera les conditions qu'il contient. Une fois terminé, il reviendra à SELECT pour. analyser le terrain. Enfin, une table virtuelle est formée.
Ce qui suit le mot clé WHERE est une expression conditionnelle. Une fois l'expression conditionnelle calculée, il y aura une valeur de retour, qui est différente de zéro ou 0. Non nulle signifie vrai (vrai) et 0 signifie faux (faux). De la même manière, la condition après WHERE a également une valeur de retour, vraie ou fausse, pour déterminer s'il faut exécuter SELECT ensuite.
L'analyseur trouve d'abord le mot-clé SELECT, puis passe au mot-clé FROM pour importer la table STUDENT dans la mémoire, trouve le premier enregistrement via le pointeur, puis trouve le mot-clé WHERE pour calculer son expression conditionnelle si c'est le cas. vrai, alors ces enregistrements sont chargés dans une table virtuelle et le pointeur pointe vers l'enregistrement suivant. Si faux, le pointeur pointe directement vers l’enregistrement suivant sans effectuer d’autres opérations. Récupérez toujours la table entière et renvoyez la table virtuelle récupérée à l'utilisateur. EXISTS fait partie d'une expression conditionnelle, qui a également une valeur de retour (vrai ou faux).

Avant d'insérer un enregistrement, vous devez vérifier si l'enregistrement existe déjà. L'opération d'insertion ne sera effectuée que lorsque l'enregistrement n'existe pas. Vous pouvez empêcher l'insertion d'enregistrements en double en utilisant l'instruction conditionnelle EXISTS.
INSERT INTO TableIn (ANAME,ASEX)
SELECT top 1 '张三', '男' FROM TableIn
OÙ n'existe pas (sélectionnez * dans TableIn où TableIn.AID = 7)

En ce qui concerne l'efficacité d'utilisation de EXISTS et IN, il est généralement plus efficace d'utiliser exist que in, car IN n'utilise pas d'index, mais l'utilisation spécifique dépend de la situation réelle :
IN convient aux situations où l'extérieur la table est grande et la table intérieure est petite ; EXISTS convient aux situations où l'apparence est petite mais l'intérieur est grand.

La différence entre in, not in, existe et not exist :

Parlons d'abord de la différence entre in et exist :
exists : existe, généralement suivi d'une sous-requête Lorsque la sous-requête renvoie le nombre de lignes, exist renvoie vrai.
sélectionnez * depuis la classe où existe (select'x"form stu où stu.cid=class.cid)
Lorsque in et exist sont comparés en termes d'efficacité de la requête, l'efficacité de la requête est plus rapide que la requête efficacité de exist
La sous-requête après exist(xxxxx) est appelée une sous-requête corrélée. Elle ne renvoie pas la valeur de la liste
renvoie simplement un résultat vrai ou faux (c'est pourquoi 'x' est sélectionné dans le. sous-requête Bien sûr, la raison peut aussi être

sélectionnez n'importe quoi) Autrement dit, il se soucie uniquement de savoir si les données entre parenthèses peuvent être trouvées et si un tel enregistrement existe.
La façon dont cela fonctionne est d'exécuter d'abord la requête principale, puis d'interroger les résultats correspondants dans la sous-requête. Si elle existe, si vrai est renvoyé,

<🎜. > sera affiché, et vice versa, si false est renvoyé, il n'y aura pas de sortie, puis la sous-requête sera interrogée en fonction de chaque ligne de la requête principale

<🎜. >

La séquence d'exécution est la suivante : 1. Exécuter d'abord une requête externe 2. Exécuter une sous-requête pour chaque ligne de la requête externe, et chaque fois que la sous-requête est exécutée, elle fera référence à l'heure. dans la requête externe

La valeur de la ligne précédente. 3. Utilisez les résultats de la sous-requête pour déterminer l'ensemble de résultats de la requête externe. Si la requête externe renvoie 100 lignes, SQL exécutera la requête 101 fois, une fois pour la requête externe, puis pour chaque ligne renvoyée par la requête externe

Une sous-requête.

in : contient Interrogez les garçons du même âge que toutes les filles sélectionnez * from stu où sex='male' et age in( select age from stu which sex='female') La sous-requête après
in() renvoie l'ensemble de résultats,
. puis la requête principale accède ensuite à l'ensemble de résultats pour trouver une liste de champs qui répondent aux exigences, sinon elle ne sera pas affichée

<🎜. >

pas dans et pas La différence entre existe : pas dans Utilisez pas dans uniquement lorsque le champ après le mot-clé select dans la sous-requête a une contrainte non nulle ou a une telle indice. De plus, si la table de la requête principale est grande, la table de la sous-requête est petite mais s'il y a beaucoup d'enregistrements, vous devez utiliser not in,
Par exemple : pour interroger les classes où il n'y a pas d'étudiants. , sélectionnez * dans la classe où cid not in (sélectionnez cid distinct de stu)
Lorsqu'il y a une valeur nulle pour cid dans le tableau, not in ne traite pas les valeurs nulles
Solution : sélectionnez * from class


où cid n'est pas dans

(sélectionnez l'ordre d'exécution de cid distinct de stu où cid n'est pas nul)

not in is : une requête qui enregistre un enregistrement dans la table (interroger chaque enregistrement) répond aux exigences. Si l'ensemble de résultats n'est pas rempli, l'ensemble de résultats sera renvoyé s'il est. ne correspond pas, l'enregistrement suivant sera interrogé jusqu'à ce que tous les enregistrements de la table soient interrogés. En d’autres termes, afin de prouver qu’il est introuvable, nous ne pouvons le prouver qu’en interrogeant tous les enregistrements. Les index ne sont pas utilisés.

n'existe pas : s'il y a peu d'enregistrements dans la table de requête principale et de nombreux enregistrements dans la table de sous-requête, et qu'il y a des index.
Par exemple : Pour interroger ces classes sans élèves, sélectionnez * dans la classe2


où il n'existe pas

(sélectionnez * de stu1 où stu1.cid =class2.cid)


not exists的执行顺序是:在表中查询,是根据索引查询的,如果存在就返回true,如果不存在就返回false,不会每条记录都去查询。
之所以要多用not exists,而不用not in,也就是not exists查询的效率远远高与not in查询的效率。

实例:

exists,not exists的使用方法示例,需要的朋友可以参考下。

学生表:create table student
(
 id number(8) primary key,
 name varchar2(10),deptment number(8)
)
Copier après la connexion
选课表:create table select_course
(
  ID         NUMBER(8) primary key,
  STUDENT_ID NUMBER(8) foreign key (COURSE_ID) references course(ID),
  COURSE_ID  NUMBER(8) foreign key (STUDENT_ID) references student(ID)
)
Copier après la connexion
课程表:create table COURSE
(
  ID     NUMBER(8) not null,
  C_NAME VARCHAR2(20),
  C_NO   VARCHAR2(10)
)
Copier après la connexion
student表的数据:
        ID NAME            DEPTMENT_ID
---------- --------------- -----------
         1 echo                   1000
         2 spring                 2000
         3 smith                  1000
         4 liter                  2000
Copier après la connexion
course表的数据:
        ID C_NAME               C_NO
---------- -------------------- --------
         1 数据库               data1
         2 数学                 month1
         3 英语                 english1
Copier après la connexion
select_course表的数据:
        ID STUDENT_ID  COURSE_ID
---------- ---------- ----------
         1    1         1
         2    1         2
         3    1         3
         4    2         1
         5    2         2
         6    3         2
Copier après la connexion
1.查询选修了所有课程的学生id、name:(即这一个学生没有一门课程他没有选的。)
Copier après la connexion
分析:如果有一门课没有选,则此时(1)select * from select_course sc where sc.student_id=ts.id
Copier après la connexion
and sc.course_id=c.id存在null,
Copier après la connexion
这说明(2)select * from course c 的查询结果中确实有记录不存在(1查询中),查询结果返回没有选的课程,
Copier après la connexion
此时select * from t_student ts 后的not exists 判断结果为false,不执行查询。
Copier après la connexion
SQL> select * from t_student ts where not exists
	 (select * from course c where not exists
  		(select * from select_course sc where sc.student_id=ts.id and sc.course_id=c.id));
Copier après la connexion
        ID NAME            DEPTMENT_ID
---------- --------------- -----------
         1 echo                   1000
Copier après la connexion
2.查询没有选择所有课程的学生,即没有全选的学生。(存在这样的一个学生,他至少有一门课没有选),
分析:只要有一个门没有选,即select * from select_course sc where student_id=t_student.id and course_id
=course.id 有一条为空,即not exists null 为true,此时select * from course有查询结果(id为子查询中的course.id ),
因此select id,name from t_student 将执行查询(id为子查询中t_student.id )。
SQL> select id,name from t_student where exists
(select * from course where not exists
(select * from select_course sc where student_id=t_student.id and course_id=course.id));
        ID NAME
---------- ---------------
         2 spring
         3 smith
         4 liter
3.查询一门课也没有选的学生。(不存这样的一个学生,他至少选修一门课程),
分析:如果他选修了一门select * from course结果集不为空,not exists 判断结果为false;
select id,name from t_student 不执行查询。
SQL> select id,name from t_student where not exists
(select * from course where exists
(select * from select_course sc where student_id=t_student.id and course_id=course.id));
        ID NAME
---------- ---------------
         4 liter
4.查询至少选修了一门课程的学生。
SQL> select id,name from t_student where exists
(select * from course where  exists
(select * from select_course sc where student_id=t_student.id and course_id=course.id));
        ID NAME
---------- ---------------
         1 echo
         2 spring
         3 smith
Copier après la connexion

本文介绍了SQL中EXISTS的用法 ,更多相关内容请关注php中文网。

相关推荐:

Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介

Mysql常用基准测试工具

Mysql函数 的相关讲解

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal