2008-10-06 4 views
2

Je cherche une requête qui me retournera une colonne supplémentaire à la fin de ma requête actuelle qui est le nombre de toutes les colonnes dans l'ensemble de retour qui contiennent une colonne nulle. Par exemple:Comment puis-je obtenir le nombre de colonnes de valeur null par ligne dans un ensemble de retour?

Col 1 - Col 2 - Col 3 
A  B  0 
A  NULL 1 
NULL NULL 2 

Yat-il un moyen simple d'obtenir cet ensemble de retour sur la base des valeurs de la ligne plutôt que d'avoir à tous les critères actualisez qui va chercher les lignes d'origine?

Répondre

0

S'il n'y a pas une très bonne raison que vous ayez besoin de faire cela dans le SQL, vous devriez juste faire une boucle for à travers le jeu de résultats et compter les valeurs NULL alors.

Le coût va de n^n à n ..

+0

@Alexander, Le coût d'exécution en termes de cycles cpu pourrait descendre, mais le coût du développeur/mainteneur en termes de compréhension du code monte. _If_ c'est la logique de base de données, je suggère de le garder dans la base de données. –

+0

@AJ, Ce n'est pas une logique de base de données, c'est une logique de modèle. Je le garderais dans le modèle. Mais je me rends compte que quelqu'un avec une telle implémentation funky peut-être n'utilise pas MVC, donc cela peut être un point discutable. Oh et comment pouvez-vous dire que SQL est compréhensible: P –

3

solution truand:

select Col1, Col2, 
     case when Col1 is null then 1 else 0 end 
    + case when Col2 is null then 1 else 0 end 
    as Col3 
from (

select 'A' as Col1, 'B' as Col2 
union select 'A', NULL 
union select NULL, NULL 

) z 

Ce retourne

Col1 Col2 Col3 
NULL NULL 2 
A NULL 1 
A B 0 
0

Vous pouvez utiliser la colonne calculée:

CREATE TABLE testTable(
    col1 nchar(10) NULL, 
    col2 nchar(10) NULL, 
    col3 AS (case when col1 IS NULL then (1) else (0) end+case when col2 IS NULL then (1) else (0) end) 
) 

Ce n'est pas si joli lution, mais devrait fonctionner.

Si vous avez affaire à un grand nombre de colonnes et que vous prévoyez de nombreuses valeurs NULL, vous pouvez utiliser sparse columns (disponible dans SQL Server 2008). Il sera optimisé pour NULL et il peut générer automatiquement une représentation XML pour chaque ligne de données de la table.

2
select count(*) - count(ColumnName) as NumberOfNulls from yourTable 

renvoie le nombre de valeurs null dans une colonne spécifique. Si vous faites cela pour chaque colonne, vous pouvez obtenir ces données.

3

Oracle a une fonction NVL2() qui rend cela facile.

select col1, 
     col2, 
     col3, 
     ... 
     NVL2(col1,0,1) 
     +NVL2(col2,0,1) 
     +NVL2(col3,0,1) coln 
from whatever 
1

Comme dans un poste similaire, SQL est pas très adapté à travailler dans les différentes colonnes dans une rangée, mais muach mieux à travailler à travers les lignes.

Je suggérerais de transformer la table en faits «individuels» à propos d'une rangée, par ex.

select <key>, col1 as value From aTable 
UNION 
select <key>, col2 as value From aTable 
UNION 
... and so on for the other columns to be summed. 

Cela peut être transformé en une vue-à-dire

create view aView as (select as above). 

Ensuite, la bonne réponse est juste

select key, count(*) 
from aView 
where value is null 
Group By key 
1
create table TEST 
(
    a VARCHAR2(10), 
    b VARCHAR2(10), 
    c VARCHAR2(10) 
); 

insert into TEST (a, b, c) 
values ('jas', 'abhi', 'shail'); 
insert into TEST (a, b, c) 
values (null, 'abhi', 'shail'); 
insert into TEST (a, b, c) 
values ('jas', null, 'shail'); 
insert into TEST (a, b, c) 
values ('jas', 'abhi', null); 
insert into TEST (a, b, c) 
values ('jas', 'abhi', 'abc|xyz'); 
insert into TEST (a, b, c) 
values ('jas', 'abhi', 'abc|xyz'); 
insert into TEST (a, b, c) 
values ('jas', 'abhi', 'abc|xyz'); 
insert into TEST (a, b, c) 
values (null, 'abhi', 'abc|xyz'); 
commit; 

select sum(nvl2(a,null,1)),sum(nvl2(b,null,1)),sum(nvl2(c,null,1)) from test 
where a is null 
or b is null 
or c is null 
order by 1,2,3 
+1

Bienvenue dans StackOverflow! S'il vous plaît essayez d'ajouter une explication au code, car il sera utile pour référence future. –

Questions connexes