309 votes

MySQL SELECT uniquement les valeurs non nulles

Est-il possible de faire une instruction de sélection qui ne prend que des valeurs NOT NULL ?

En ce moment, j'utilise ceci :

SELECT * FROM table

Et ensuite je dois filtrer les valeurs nulles avec une boucle php.

Y a-t-il un moyen de le faire :

SELECT * (that are NOT NULL) FROM table

?

Actuellement, lorsque je sélectionne *, j'obtiens val1,val2,val3,null,val4,val5,null,null etc.... mais je veux juste obtenir les valeurs qui ne sont pas nulles dans mon résultat. Est-ce possible sans filtrer avec une boucle ?

2 votes

Que voulez-vous qu'il se passe s'il y a une ligne où certaines colonnes ont des valeurs NULL et d'autres des valeurs non NULL ?

0 votes

Je voudrais obtenir uniquement les valeurs des colonnes qui ne sont pas nulles, et renvoyer uniquement les valeurs des colonnes de la ligne qui ne sont pas nulles. Actuellement, j'utilise une boucle pour les filtrer. Est-il possible de le faire sans boucle ?

1 votes

@bryan - Quelle est la structure de votre table ? Toutes les colonnes ont-elles le même type de données ?

516voto

Martin Smith Points 174101

Vous devez utiliser IS NOT NULL . (Les opérateurs de comparaison = y <> les deux donnent UNKNOWN con NULL de part et d'autre de l'expression).

SELECT * 
FROM table 
WHERE YourColumn IS NOT NULL;

Par souci d'exhaustivité, j'ajouterai que dans MySQL, vous pouvez également annuler l'attribut opérateur d'égalité à sécurité nulle mais ce n'est pas du SQL standard.

SELECT *
FROM table 
WHERE NOT (YourColumn <=> NULL);

Modifié pour refléter les commentaires. Il semble que votre table ne soit pas en première forme normale, auquel cas modifier la structure pourrait vous faciliter la tâche. Il existe cependant quelques autres façons de procéder...

SELECT val1 AS val
FROM  your_table
WHERE val1 IS NOT NULL
UNION ALL
SELECT val2 
FROM  your_table
WHERE val2 IS NOT NULL
/*And so on for all your columns*/

L'inconvénient de la méthode ci-dessus est qu'elle scanne le tableau plusieurs fois, une fois pour chaque colonne. Cela peut éventuellement être évité par la méthode ci-dessous, mais je ne l'ai pas testée dans MySQL.

SELECT CASE idx
         WHEN 1 THEN val1
         WHEN 2 THEN val2
       END AS val
FROM   your_table
        /*CROSS JOIN*/
       JOIN (SELECT 1 AS idx
                   UNION ALL
                   SELECT 2) t
HAVING val IS NOT NULL  /*Can reference alias in Having in MySQL*/

2 votes

Merci beaucoup. Cela m'a aidé :)

0 votes

Dans la dernière approche, vous avez utilisé CASE déclaration, et non CASE fonction. Donc, cela ne devrait-il pas être END CASE au lieu de END dans le SELECT CASE ... partie ?

0 votes

Pour les personnes non expertes, pouvez-vous expliquer la dernière solution ? Est-ce que la idx e premier SELECT proviennent de la idx dans la seconde SELECT ? Que fait le CASE de l'énoncé tente d'accomplir ? Que fait la deuxième SELECT font-ils réellement ? Et vous faites une jointure interne, pas une jointure croisée, n'est-ce pas ?

22voto

Mark Byers Points 318575

Vous pouvez filtrer les lignes qui contiennent une valeur NULL dans une colonne spécifique :

SELECT col1, col2, ..., coln
FROM yourtable
WHERE somecolumn IS NOT NULL

Si vous voulez filtrer les lignes qui contiennent un null dans une colonne, essayez ceci :

SELECT col1, col2, ..., coln
FROM yourtable
WHERE col1 IS NOT NULL
AND col2 IS NOT NULL
-- ...
AND coln IS NOT NULL

Mise à jour : D'après vos commentaires, peut-être voulez-vous ceci ?

SELECT * FROM
(
    SELECT col1 AS col FROM yourtable
    UNION
    SELECT col2 AS col FROM yourtable
    UNION
    -- ...
    UNION
    SELECT coln AS col FROM yourtable
) T1
WHERE col IS NOT NULL

Et je suis d'accord avec Martin pour dire que si vous devez faire cela, vous devriez probablement modifier la conception de votre base de données.

0 votes

Je ne suis pas sûr de l'avoir bien expliqué, mais je vais essayer de faire un peu mieux. Actuellement, lorsque je sélectionne *, j'obtiens val1,val2,val3,null,val4,val5,null,null etc.... mais je veux juste obtenir les valeurs qui ne sont pas nulles dans mon résultat. Est-ce possible sans filtrer avec une boucle ?

0 votes

@bryan - Pourriez-vous expliquer quelles colonnes * retours ? Vous pourriez peut-être fournir un exemple de données dans votre question, car votre commentaire ci-dessus n'indique pas clairement s'il s'agit d'une seule colonne.

0 votes

Actuellement, * renvoie toutes les valeurs de la ligne, c'est-à-dire val1, val2, val3, null, val4, val5, null, null. Mais je veux qu'elle ne renvoie que les valeurs des colonnes qui ne sont pas nulles. Pour l'instant, je le fais avec une boucle pour filtrer les valeurs après le retour du résultat.

13voto

Alan Chavez Points 69
Select * from your_table 
WHERE col1 and col2 and col3 and col4 and col5 IS NOT NULL;

Le seul inconvénient de cette approche est que vous ne pouvez comparer que 5 colonnes, après quoi le résultat sera toujours faux, c'est pourquoi je ne compare que les champs qui peuvent l'être. NULL .

8voto

porquero Points 434

J'ai trouvé cette solution :

Cette requête sélectionne la dernière valeur non nulle pour chaque colonne.

Ejemplo


Si vous avez une table :

id|title|body
1 |t1   |b1
2 |NULL |b2
3 |t3   |NULL

vous obtenez :

title|body
t3   |b2

Requête


SELECT DISTINCT (

  SELECT title
  FROM test
  WHERE title IS NOT NULL 
  ORDER BY id DESC 
  LIMIT 1
) title, (

  SELECT body
  FROM test
  WHERE body IS NOT NULL 
  ORDER BY id DESC 
  LIMIT 1
) body
FROM test

J'espère vous aider.

0 votes

GROUP_CONCAT(corps) AS corps

2voto

Marko Points 151

Il n'y a pas de moyen efficace de faire ce qui suit ou je n'en suis pas conscient.

SELECT * (qui ne sont PAS NULL) FROM table ?

Mais il est certain que dans le choix de votre langage de programmation, il y a quelque chose qui peut vous aider, par exemple avec php vous pouvez utiliser array_filter() sans fonction de rappel

    //$db as you new or established mysqli instance
if ($result = $db->query("SELECT * FROM yourtable"))
{
    while($full_row = $result->fetch_assoc()){
        // following removes from result (NULL, null, false, '')
        $return_clean[] = array_filter($full_row);
    }
    $result->free();
    print_r($return_clean);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X