Rechercher un champ vide avec MySQL

100

J'ai écrit une requête pour vérifier les utilisateurs avec certains critères, l'un étant qu'ils ont une adresse e-mail.

Notre site permettra à un utilisateur d'avoir ou non une adresse email.

$aUsers=$this->readToArray('
 SELECT `userID` 
 FROM `users` 
 WHERE `userID` 
 IN(SELECT `userID`
         FROM `users_indvSettings`
  WHERE `indvSettingID`=5 AND `optionID`='.$time.')
  AND `email`!=""
 ');

Est-ce la meilleure façon de rechercher un champ vide dans SQL? Je viens d'essayer "IS NOT NULL" et cela a quand même renvoyé un enregistrement d'utilisateurs sans qu'ils aient une adresse e-mail.

La requête ci-dessus fonctionne mais par curiosité, je me suis demandé si je le fais correctement.


la source

Réponses:

274

Un champ vide peut être une chaîne vide ou un NULL.

Pour gérer les deux, utilisez:

email > ''

qui peut bénéficier de l' rangeaccès si vous avez beaucoup d'enregistrements d'e-mails vides (les deux types) dans votre table.

Quassnoi
la source
11
Quel est l'inverse de cela? (Pour quand vous ne voulez que des champs NULL ou '')
Keylan
1
@Keylan: pas d'expression unique.
Quassnoi
5
@Keylan:! (Email> '')
SEoF
3
@SEoF: cela ne correspondra pasNULL
Quassnoi
2
J'ai le même commentaire que celui de Quassnoi. J'émets "select orig_id, hotline from normal_1952 where! (Hotline> '')" et il y a un enregistrement avec une hotline nulle mais ça ne correspond pas. J'utilise MySQL 5.6
Scott Chu
38

Oui, ce que vous faites est correct. Vous vérifiez que le champ e-mail n'est pas une chaîne vide. NULL signifie que les données sont manquantes. Une chaîne vide"" est une chaîne vide d'une longueur de 0.

Vous pouvez également ajouter la vérification nulle

AND (email != "" OR email IS NOT NULL)
Yada
la source
1
Votre expression correspondra également aux chaînes vides. OR email IS NOT NULLest ici redondant (cela est impliqué par la condition précédente).
Quassnoi
1
Intéressant, cela renvoie toujours les enregistrements qui ont un emailchamp vide .
13
Le OU doit être un ET ici. "OR email IS NOT NULL" correspondra à une chaîne d'e-mail vide d'une longueur de 0.
pdavis
Remarquez le commentaire de pdavis "OU DEVRAIT ÊTRE ET"
débutant
13

Vous pourriez utiliser

IFNULL(email, '') > ''
Mathieu de Lorimier
la source
2
Génial! Et vous n'avez pas besoin du TRIM. Pour inverser, utilisez IFNULL (email, '') = ''.
mauromartini
2

Il y a une différence entre une chaîne vide (email! = "") Et NULL. NULL est nul et une chaîne vide est quelque chose.

Leslie
la source
Pourquoi AND (email! = "" OR email IS NOT NULL) échoue?
3
devrait êtreAND (email != '' AND email IS NOT NULL)
thetaiko
@thetaiko: email IS NOT NULLest ici redondant. !=le prédicat ne correspondra jamais à une NULLvaleur.
Quassnoi
et si vous essayez: AND (trim (email)! = '')
Leslie
Je sais que je "suis assez tard pour cette discussion, mais la déclaration fonctionnera si vous inversez l'ordre:" AND ((email IS NOT NULL) AND (email! = '')). Si elle est évaluée dans l'autre ordre, l'instruction est évaluée comme nulle (pas TRUE) si l'adresse e-mail est NULL, et ne sera donc ni VRAI ni FAUX. Le chèque IS NULL doit donc venir en PREMIER!
Curt
2

Cela fonctionnera mais il est toujours possible qu'un enregistrement nul soit renvoyé. Bien que vous définissiez l'adresse e-mail sur une chaîne de longueur zéro lorsque vous insérez l'enregistrement, vous souhaiterez peut-être toujours gérer le cas d'une adresse e-mail NULL entrant d'une manière ou d'une autre dans le système.

     $aUsers=$this->readToArray('
     SELECT `userID` 
     FROM `users` 
     WHERE `userID` 
     IN(SELECT `userID`
               FROM `users_indvSettings`
               WHERE `indvSettingID`=5 AND `optionID`='.$time.')
     AND `email` != "" AND `email` IS NOT NULL
     ');
pdavis
la source
La requête de @ op ne laisse aucune possibilité de NULLretour de l' enregistrement.
Quassnoi
-3

vérifiez ce code pour le problème:

$sql = "SELECT * FROM tablename WHERE condition";

$res = mysql_query($sql);

while ($row = mysql_fetch_assoc($res)) {

    foreach($row as $key => $field) {  

        echo "<br>";

        if(empty($row[$key])){

            echo $key." : empty field :"."<br>"; 

        }else{

        echo $key." =" . $field."<br>";     

        }
    }
}
user3103831
la source
Il existe de meilleures façons de faire cela dans une requête sans avoir à parcourir chaque ligne
Jiho Kang