web-dev-qa-db-fra.com

Rechercher toutes les lignes avec une valeur nulle dans une colonne

J'essaie de créer une requête qui renverra toutes les lignes ayant une valeur nulle dans toutes les colonnes sauf une. Certaines lignes auront plus d'une entrée nulle quelque part. Il y a une colonne que je veux exclure, car à ce moment toutes les entrées sont nulles et c'est la seule colonne autorisée à avoir des valeurs nulles. Je suis coincé parce que je ne sais pas comment inclure toutes les colonnes du WHERE.

SELECT *
FROM Analytics
WHERE * IS NULL

Alternativement, je peux faire un compte pour une colonne, mais la table compte environ 67 colonnes.

SELECT COUNT(*)
FROM Analytics
WHERE P_Id IS NULL
12
Snake_Plissken

Dans SQL Server, vous pouvez emprunter l’idée de cette réponse

;WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema-instance' as ns)
SELECT *
FROM   Analytics
WHERE  (SELECT Analytics.*
        FOR xml path('row'), elements xsinil, type
        ).value('count(//*[local-name() != "colToIgnore"]/@ns:nil)', 'int') > 0

SQL Fiddle

Construire une requête avec 67 colonnes sera probablement plus efficace, mais cela évitera quelques saisies ou le besoin de SQL dynamique pour la générer.

10
Martin Smith

Je n'ai pas une telle table à tester, en supposant qu'il n'y ait pas de 'x' comme données dans un champ, je pense que cela devrait fonctionner sur Sql-Server; ( DÉMO )

NOTE: J'ai filtré keyColumn en tant que c.name != 'keyColumn'

DECLARE @S NVARCHAR(max), @Columns VARCHAR(50), @Table VARCHAR(50)

SELECT @Columns = '66', --Number of cols without keyColumn
       @Table = 'myTable'

SELECT @S =  ISNULL(@S+'+ ','') + 'isnull(convert(nvarchar, ' + c.name + '),''x'')'  
FROM sys.all_columns c 
WHERE c.object_id = OBJECT_ID(@Table) AND c.name != 'keyColumn'

exec('select * from '+@Table+' where ' + @S + '= replicate(''x'',' + @Columns + ')')
1
Kaf

Selon le SGBDR que vous utilisez, je pense que votre seule option (plutôt que de dire explicitement WHERE col1 IS NULL and col2 IS NULL and col3 IS NULL ...) serait d'utiliser le SQL dynamique.

Par exemple, si vous souhaitez obtenir tous les noms de colonne d'une base de données SQL Server, vous pouvez utiliser quelque chose comme ceci pour renvoyer ces noms:

SELECT
     name
FROM
     sys.columns
WHERE
     object_id = OBJECT_ID('DB.Schema.Table')

Vous pouvez utiliser FOR XML pour créer votre clause WHERE:

SELECT Name + ' IS NULL AND ' AS [text()]
FROM sys.columns c1
WHERE     object_id = OBJECT_ID('DB.Schema.Table')
ORDER BY Name
FOR XML PATH('')

J'espère que cela vous aide à démarrer.

Bonne chance.

0
sgeddes