Maison base de données tutoriel mysql Compréhension approfondie de Null dans SQL

Compréhension approfondie de Null dans SQL

May 01, 2017 pm 01:43 PM

NULL représente l'inconnu et l'incertitude dans le monde de l'informatique et de la programmation. Bien que la traduction chinoise soit « vide », ce vide (nul) n’est pas si vide (vide). Null représente un état inconnu, un état futur. Par exemple, je ne sais pas combien d'argent Xiao Ming a en poche, mais je ne peux pas être sûr que ce soit 0. À l'heure actuelle, Null est utilisé dans les ordinateurs pour représenter. inconnu et incertain.

Même si les personnes maîtrisant SQL n'auront aucun doute sur Null, il est toujours difficile de trouver un article qui le résume de manière exhaustive. J'ai vu une version anglaise et ça m'a fait du bien.

Tony Hoare a inventé la référence nulle en 1965 et la considérait comme son « erreur d'un milliard de dollars ». Même aujourd'hui, 50 ans plus tard, les valeurs nulles en SQL sont toujours responsables de nombreuses erreurs courantes.

Jetons un coup d’œil à certaines des situations les plus choquantes.

Null ne prend pas en charge le jugement de taille/égalité

Pour les deux requêtes suivantes, quel que soit le nombre d'enregistrements présents dans la table des utilisateurs, les enregistrements renvoyés comportent 0 ligne :

1

2

3

4

5

6

7

select * from users where deleted_at = null;

 

– result: 0 rows

 

select * from users where deleted_at != null;

 

– result: 0 rows

Copier après la connexion

Comment est-ce possible ? Tout cela parce que null représente un type "inconnu". Autrement dit, cela n’a aucun sens d’utiliser des opérateurs conditionnels normaux pour comparer null avec d’autres valeurs. Null n'est pas égal à Null (compréhension approximative : une valeur inconnue ne peut pas être égale à une valeur inconnue, et la relation entre les deux est également inconnue, sinon les mathématiques et la logique seront gâchées).

– Remarque : le SQL suivant convient à MySQL. S'il s'agit d'Oracle, vous devez ajouter … from dual;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

select null > 0;

 

– result: null

 

select null < 0;

 

– result: null

 

select null = 0;

 

– result: null

 

select null = null;

 

– result: null

 

select null != null;

 

– result: null

Copier après la connexion

. La bonne façon de comparer une valeur à null est d'utiliser le mot-clé is et l'opérateur is not :

1

2

3

4

5

select * from users

 

where deleted_at is null;

 

– result: 所有被标记为删除的 users

Copier après la connexion

1

2

3

4

5

select * from users

 

where deleted_at is not null;

 

– result: 所有被标记为删除的 users

Copier après la connexion

Si vous souhaitez déterminer si les valeurs de deux colonnes sont différentes, vous pouvez utiliser est distinct de :

1

2

3

4

5

select * from users

 

where has_address is distinct from has_photo

 

– result: 地址(address)或照片(photo)两者只有其一的用户

Copier après la connexion

pas avec Null

La sous-requête (sous-sélection) est un moyen très pratique de filtrer les données. Par exemple, si vous souhaitez interroger des utilisateurs qui n'ont aucun package, vous pouvez écrire une requête comme celle-ci :

1

2

3

select * from users 

 

where id not in (select user_id from packages)

Copier après la connexion

Mais à ce moment-là, si le user_id d'une ligne de la table packages est nul, un problème survient : le résultat renvoyé est vide ! Pour comprendre pourquoi cette chose étrange se produit, nous devons comprendre ce que le compilateur SQL a fait. exemple :

1

2

3

select * from users 

 

where id not in (1, 2, null)

Copier après la connexion

Cette instruction SQL sera convertie en :

1

2

3

select * from users 

 

where id != 1 and id != 2 and id != null

Copier après la connexion

Nous savons que le résultat de id != null est une valeur inconnue, null Et le résultat de l'opération AND entre n'importe quelle valeur et null est nul, il n'est donc équivalent à aucune autre condition. La raison de ce résultat est que la logique. la valeur de null n'est pas vraie.

Si les conditions sont inversées, il n'y aura aucun problème avec les résultats de la requête. Maintenant, nous interrogeons les utilisateurs avec des packages.

1

2

3

select * from users 

 

where id in (select user_id from packages)

Copier après la connexion

​De même, nous pouvons utiliser un exemple simple :

1

2

3

select * from users

 

where id in (1, 2, null)

Copier après la connexion

Ce SQL est converti en :

1

2

3

select * from users 

 

where id = 1 or id = 2 or id = null

Copier après la connexion

Étant donné que la clause Where est une série de conditions ou, peu importe si l'une d'elles aboutit à la valeur null. Les valeurs non vraies n'affectent pas les résultats de calcul des autres parties de la clause et équivalent à être ignorées.

Null et tri

Lors du tri, la valeur nulle est considérée comme la plus grande. Cela vous causera beaucoup de maux de tête lors du tri par ordre décroissant (décroissant), car la valeur nulle vient en premier.

La requête suivante consiste à afficher les classements des utilisateurs en fonction des scores, mais elle classe les utilisateurs sans scores au sommet

1

2

3

4

5

6

7

select name, points

 

from users

 

order by 2 desc;

 

– points 为 null 的记录排在所有记录之前!

Copier après la connexion

 ! Il existe deux manières d’envisager la résolution de ce type de problème. Le plus simple est d'utiliser coalesce pour éliminer l'effet de null :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

– 在输出时将 null 转换为 0 :

 

select name, coalesce(points, 0)

 

from users

 

order by 2 desc;

 

– 输出时保留 null, 但排序时转换为 0 :

 

select name, points

 

from users

 

order by coalesce(points, 0) desc;

Copier après la connexion

Il existe une autre méthode qui nécessite la prise en charge de la base de données, qui consiste à spécifier s'il faut mettre la valeur nulle en premier ou en dernier lors du tri :

1

2

3

4

5

select name, coalesce(points, 0)

 

from users

 

order by 2 desc nulls last;

Copier après la connexion

Bien entendu, null peut également être utilisé pour éviter que des erreurs ne se produisent, telles que la gestion des erreurs d'opérations mathématiques lorsque le diviseur est nul.

Divisé par 0

Diviser par zéro est une erreur très pénible. SQL qui fonctionnait correctement hier s'est soudainement détérioré lorsqu'il a été divisé par 0. Une solution courante consiste à utiliser d’abord une instruction case pour déterminer si le dénominateur est 0, puis à effectuer l’opération de division.

1

2

3

select case when num_users = 0 then 0 

 

else total_sales/num_users end;

Copier après la connexion

La manière de faire l'instruction ase est en fait moche et le dénominateur est réutilisé. Si c'est une situation simple, ça va. Mais si le dénominateur est une expression très complexe, alors une tragédie surviendra : c'est difficile à lire, difficile à maintenir et à modifier, et il y aura beaucoup de bugs si vous n'y faites pas attention.

À ce stade, nous pouvons examiner les avantages de null. Utilisez nullif pour que le dénominateur devienne nul lorsqu'il est égal à 0. De cette façon, une erreur ne sera plus signalée lorsque num_users = 0, le résultat renvoyé devient nul.

1

2

3

select total_sales/nullif(num_users, 0);

 

nullif 是将其他值转为 null, 而Oracle的 nvl 是将 null 转换为其他值。

Copier après la connexion
Si vous ne voulez pas de null, mais que vous souhaitez convertir en 0 ou en d'autres nombres, vous pouvez utiliser la fonction de fusion basée sur le SQL précédent :

1

2

3

select coalesce(total_sales/nullif(num_users, 0), 0);

 

null 再转换回0

Copier après la connexion

Conclusion

Tony Hoare regrette peut-être son erreur, mais au moins le problème de null peut être facilement résolu. Alors allez pratiquer votre nouveau coup ultime et restez à l'écart de la fosse invalide (annulante) creusée par null !

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!

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

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Tags d'article chaud

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Quelle est la différence entre HQL et SQL dans le framework Hibernate ? Quelle est la différence entre HQL et SQL dans le framework Hibernate ? Apr 17, 2024 pm 02:57 PM

Quelle est la différence entre HQL et SQL dans le framework Hibernate ?

Utilisation de l'opération de division dans Oracle SQL Utilisation de l'opération de division dans Oracle SQL Mar 10, 2024 pm 03:06 PM

Utilisation de l'opération de division dans Oracle SQL

Que signifie l'attribut d'identité dans SQL ? Que signifie l'attribut d'identité dans SQL ? Feb 19, 2024 am 11:24 AM

Que signifie l'attribut d'identité dans SQL ?

Comparaison et différences de syntaxe SQL entre Oracle et DB2 Comparaison et différences de syntaxe SQL entre Oracle et DB2 Mar 11, 2024 pm 12:09 PM

Comparaison et différences de syntaxe SQL entre Oracle et DB2

Explication détaillée de la fonction Définir la balise dans les balises SQL dynamiques MyBatis Explication détaillée de la fonction Définir la balise dans les balises SQL dynamiques MyBatis Feb 26, 2024 pm 07:48 PM

Explication détaillée de la fonction Définir la balise dans les balises SQL dynamiques MyBatis

Comment résoudre l'erreur 5120 dans SQL Comment résoudre l'erreur 5120 dans SQL Mar 06, 2024 pm 04:33 PM

Comment résoudre l'erreur 5120 dans SQL

Comment utiliser les instructions SQL pour l'agrégation de données et les statistiques dans MySQL ? Comment utiliser les instructions SQL pour l'agrégation de données et les statistiques dans MySQL ? Dec 17, 2023 am 08:41 AM

Comment utiliser les instructions SQL pour l'agrégation de données et les statistiques dans MySQL ?

Concurrence en technologie de base de données : quelles sont les différences entre Oracle et SQL ? Concurrence en technologie de base de données : quelles sont les différences entre Oracle et SQL ? Mar 09, 2024 am 08:30 AM

Concurrence en technologie de base de données : quelles sont les différences entre Oracle et SQL ?

See all articles