Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySql, Postgres, Oracle et SQLServer ignorent le filtre IS NOT NULL

Pour omettre la ligne du résultat si l'une des sources lignes pour le même id a value IS NULL , une solution en Postgres serait d'utiliser la fonction d'agrégation every() ou (synonyme pour des raisons historiques) bool_and() dans le HAVING clause :

SELECT id
     , max(case when colID = 1 then value else '' end) AS fn
     , max(case when colID = 2 then value else '' end) AS ln
     , max(case when colID = 3 then value else '' end) AS jt
FROM   tbl 
GROUP  BY id
HAVING every(value IS NOT NULL);

SQL Fiddle.

Expliquez

Votre tentative avec un WHERE la clause en éliminerait simplement une ligne source pour id = 3 dans votre exemple (celui avec colID = 1 ), en laissant deux autres pour le même id . Nous obtenons donc toujours une ligne pour id = 3 dans le résultat après agrégation.

Mais puisque nous n'avons pas de ligne avec colID = 1 , nous obtenons une chaîne vide (note :pas un NULL valeur !) pour fn dans le résultat pour id = 3 .

Une solution plus rapide dans Postgres serait d'utiliser crosstab() . Détails :

Autre SGBDR

Tandis que EVERY est défini dans la norme SQL:2008, de nombreux SGBDR ne le prennent pas en charge, probablement parce que certains d'entre eux ont des implémentations douteuses du type booléen. (Ne supprimez aucun nom comme "MySQL" ou "Oracle" ...). Vous pouvez probablement remplacer partout (y compris Postgres) par :

SELECT id
     , max(case when colID = 1 then value else '' end) AS fn
     , max(case when colID = 2 then value else '' end) AS ln
     , max(case when colID = 3 then value else '' end) AS jt
FROM   tbl 
GROUP  BY id
HAVING count(*) = count(value);

Parce que count() ne compte pas les valeurs NULL. Dans MySQL, il y a aussi bit_and() .Plus d'informations sous cette question connexe :