Solutions multiples pour: certaines valeurs nulles, toutes les valeurs nulles, colonnes simples et multiples, plus une utilisation rapide en utilisant le Top 1
Si vous devez tester plusieurs colonnes, vous pouvez utiliser les éléments suivants:
Column_1 Column_2 Column_3
-------- -------- --------
1 2 NULL
1 NULL NULL
5 6 NULL
Tout d'abord , testez les valeurs NULL et comptez-les:
select
sum(case when Column_1 is null then 1 else 0 end) as Column_1,
sum(case when Column_2 is null then 1 else 0 end) as Column_2,
sum(case when Column_3 is null then 1 else 0 end) as Column_3,
from TestTable
Donne un nombre de NULLs:
Column_1 Column_2 Column_3
0 1 3
Lorsque le résultat est 0, il n'y a pas de NULL.
Deuxièmement , comptons les non NULL:
select
sum(case when Column_1 is null then 0 else 1 end) as Column_1,
sum(case when Column_2 is null then 0 else 1 end) as Column_2,
sum(case when Column_3 is null then 0 else 1 end) as Column_3,
from TestTable
... Mais parce que nous comptons ici les valeurs non NULL, cela peut être simplifié pour:
select
count(Column_1) as Column_1,
count(Column_2) as Column_2,
count(Column_3) as Column_3,
from TestTable
Soit on donne:
Column_1 Column_2 Column_3
3 2 0
Lorsque le résultat est 0, la colonne est entièrement composée de valeurs NULL.
Enfin , si vous avez seulement besoin de vérifier une colonne spécifique, alors TOP 1 est plus rapide car il devrait s'arrêter au premier hit. Vous pouvez ensuite éventuellement utiliser count (*) pour donner un résultat de style booléen:
select top 1 'There is at least one NULL' from TestTable where Column_3 is NULL
select count(*) from (select top 1 'There is at least one NULL' AS note from TestTable where Column_3 is NULL) a
0 = Il n'y a pas de NULL, 1 = Il y a au moins un NULL
ou
select top 1 'There is at least one non-NULL' AS note from TestTable where Column_3 is not NULL
select count(*) from (select top 1 'There is at least one non-NULL' AS note from TestTable where Column_3 is not NULL) a
0 = Ils sont tous NULL, 1 = Il y a au moins un non NULL
J'espère que ça aide.
UNPIVOT traduit les colonnes en lignes. Dans le processus, il élimine les valeurs NULL ( référence ).
Compte tenu de l'entrée
la requête UNPIVOT
produira la sortie
Malheureusement, la ligne 4 a été entièrement éliminée car elle ne contient que des valeurs NULL! Il peut être facilement réintroduit en injectant une valeur fictive dans la requête source:
En agrégeant les lignes sur l'ID, nous pouvons compter les valeurs non nulles. Une comparaison avec le nombre total de colonnes dans la table source identifiera les lignes contenant un ou plusieurs NULL.
Je calcule 3 comme
nombre de colonnes dans la table source #t
+ 1 pour la colonne factice injectée
- 1 pour l'ID, qui n'est pas UNPIVOTED
Cette valeur peut être obtenue au moment de l'exécution en examinant les tables du catalogue.
Les lignes d'origine peuvent être récupérées en se joignant aux résultats.
Si des valeurs autres que NULL doivent être recherchées, elles peuvent être incluses dans une clause where:
Discussion
Cela nécessite un identifiant qui est acheminé via l'UNPIVOT. Une clé serait la meilleure. Si aucun n'existe, un peut être injecté par la fonction de fenêtre ROW_NUMBER () , bien que cela puisse être coûteux à exécuter.
Toutes les colonnes doivent être explicitement répertoriées dans la clause UNPIVOT. Ils peuvent être glissés dans SSMS, comme l'a suggéré @ db2. Il ne sera pas dynamique lorsque la définition de la table chagnera, comme le serait la suggestion d'Aaron Bertrand. C'est cependant le cas pour presque tous les SQL.
Pour mon ensemble de données plutôt limité, le plan d'exécution est une analyse d'index en cluster et un agrégat de flux. Cela coûtera plus de mémoire qu'un simple scan de la table et beaucoup de clauses OR.
la source