SQL:仅选择具有NULL值的列
时间:2020-03-05 18:53:34 来源:igfitidea点击:
如何选择表中所有行仅包含NULL值的所有列?我正在使用MS SQL Server2005. 我试图找出表中未使用的列,因此可以删除它们。
解决方案
回答
SELECT cols FROM table WHERE cols IS NULL
回答
我们可能需要澄清一下。我们真正要完成的任务是什么?如果我们真的想找出仅包含空值的列名,那么我们将不得不遍历scheama并基于此进行动态查询。
我不知道我们使用的是哪个DBMS,因此我将在此处放置一些伪代码。
for each col begin @cmd = 'if not exists (select * from tablename where ' + col + ' is not null begin print ' + col + ' end' exec(@cmd) end
回答
还是只想查看一列是否只有NULL值(因此可能未使用)?
进一步澄清该问题可能会有所帮助。
编辑:
好的..这是一些很粗糙的代码,可以...
SET NOCOUNT ON DECLARE @TableName Varchar(100) SET @TableName='YourTableName' CREATE TABLE #NullColumns (ColumnName Varchar(100), OnlyNulls BIT) INSERT INTO #NullColumns (ColumnName, OnlyNulls) SELECT c.name, 0 FROM syscolumns c INNER JOIN sysobjects o ON c.id = o.id AND o.name = @TableName AND o.xtype = 'U' DECLARE @DynamicSQL AS Nvarchar(2000) DECLARE @ColumnName Varchar(100) DECLARE @RC INT SELECT TOP 1 @ColumnName = ColumnName FROM #NullColumns WHERE OnlyNulls=0 WHILE @@ROWCOUNT > 0 BEGIN SET @RC=0 SET @DynamicSQL = 'SELECT TOP 1 1 As HasNonNulls FROM ' + @TableName + ' (nolock) WHERE ''' + @ColumnName + ''' IS NOT NULL' EXEC sp_executesql @DynamicSQL set @RC=@@rowcount IF @RC=1 BEGIN SET @DynamicSQL = 'UPDATE #NullColumns SET OnlyNulls=1 WHERE ColumnName=''' + @ColumnName + '''' EXEC sp_executesql @DynamicSQL END ELSE BEGIN SET @DynamicSQL = 'DELETE FROM #NullColumns WHERE ColumnName=''' + @ColumnName+ '''' EXEC sp_executesql @DynamicSQL END SELECT TOP 1 @ColumnName = ColumnName FROM #NullColumns WHERE OnlyNulls=0 END SELECT * FROM #NullColumns DROP TABLE #NullColumns SET NOCOUNT OFF
是的,有更简单的方法,但是我现在要开会。祝你好运!
回答
我们必须遍历一组列并检查每个列。我们应该能够使用DESCRIBE table命令获得所有列的列表。
伪代码:
可以更改为
foreach $column ($cols) { query("SELECT count(*) FROM table WHERE $column IS NOT NULL") if($result is zero) { # $column contains only null values" push @onlyNullColumns, $column; } else { # $column contains non-null values } } return @onlyNullColumns; I know this seems a little counterintuitive but SQL does not provide a native method of selecting columns, only rows. Answer You can do: select count(<columnName>) from <tableName>
如果要使其自动化,则可以使用系统表来迭代我们感兴趣的表中的列名
回答
我还建议搜索所有具有相同值的字段,而不仅仅是NULL。
也就是说,对于每个表中的每一列都执行查询:
select case(count(<columnName>)) when 0 then 'Nulls Only' else 'Some Values' end from <tableName>
并专注于结果返回1的那些。
回答
这应该为我们提供表" Person"中所有列只有NULL值的列表。我们将获得多个结果集的结果,这些结果集为空或者包含单个列的名称。我们需要在两个地方替换" Person"才能将其与另一个表一起使用。
SELECT COUNT(DISTINCT field) FROM tableName
回答
这是sql 2005或者更高版本:用表名替换ADDR_Address。
DECLARE crs CURSOR LOCAL FAST_FORWARD FOR SELECT name FROM syscolumns WHERE id=OBJECT_ID('Person') OPEN crs DECLARE @name sysname FETCH NEXT FROM crs INTO @name WHILE @@FETCH_STATUS = 0 BEGIN EXEC('SELECT ''' + @name + ''' WHERE NOT EXISTS (SELECT * FROM Person WHERE ' + @name + ' IS NOT NULL)') FETCH NEXT FROM crs INTO @name END CLOSE crs DEALLOCATE crs
回答
如果我们需要列出所有列值为NULL的所有行,那么我将使用COLLATE函数。这将获取值列表,并返回第一个非空值。如果将所有列名添加到列表中,然后使用" IS NULL",则应该获得仅包含空值的所有行。
declare @col varchar(255), @cmd varchar(max) DECLARE getinfo cursor for SELECT c.name FROM sys.tables t JOIN sys.columns c ON t.Object_ID = c.Object_ID WHERE t.Name = 'ADDR_Address' OPEN getinfo FETCH NEXT FROM getinfo into @col WHILE @@FETCH_STATUS = 0 BEGIN SELECT @cmd = 'IF NOT EXISTS (SELECT top 1 * FROM ADDR_Address WHERE [' + @col + '] IS NOT NULL) BEGIN print ''' + @col + ''' end' EXEC(@cmd) FETCH NEXT FROM getinfo into @col END CLOSE getinfo DEALLOCATE getinfo
我们实际上不应该有任何表的所有columns
为空,因为这意味着我们没有primary key
(不允许为null
)。没有主键是可以避免的。这会破坏第一个范式。
代码数量不匹配