如何检测和删除仅包含空值的列?

时间:2009-11-03 07:58:59

标签: sql sql-server-2005

在我的表 table1 中,有6列地点,a,b,c,d,e。

Locations [a]   [b]   [c]  [d]   [e]

[1]       10.00 Null  Null 20.00 Null

[2]       Null  30.00 Null Null  Null

我需要像

这样的结果
Locations [a]   [b]   [d]

[1]       10.00 Null  20.00

[2]       Null  30.00 Null

我的问题是如何使用sql查询检测和删除包含所有空值的列。 有可能吗?

如果是,请帮助并提供样品。

6 个答案:

答案 0 :(得分:5)

这是一个快速(且丑陋)的存储过程,它获取表的名称并打印(或者如果你想要的话,删除)充满空值的字段。

ALTER procedure mysp_DropEmptyColumns 
  @tableName nvarchar(max)
as begin
  declare @FieldName nvarchar(max)
  declare @SQL nvarchar(max)
  declare @CountDef nvarchar(max)
  declare @FieldCount int

  declare fieldNames cursor  local fast_forward for
    select c.name
      from syscolumns c 
        inner join sysobjects o on c.id=o.id
      where o.xtype='U'
        and o.Name=@tableName

  open fieldNames 
  fetch next from fieldNames into @FieldName
  while (@@fetch_status=0)
  begin
    set @SQL=N'select @Count=count(*) from "'+@TableName+'" where "'+@FieldName+'" is not null'
    SET @CountDef = N'@Count int output';
    exec sp_executeSQL @SQL, @CountDef, @Count = @FieldCount output
    if (@FieldCount=0)
    begin
      set @SQL = 'alter table '+@TableName+' drop column '+@FieldName
      /* exec sp_executeSQL @SQL */
      print @SQL
    end
    fetch next from fieldNames into @FieldName
  end

  close fieldNames
end

这使用了一个游标,并且有点慢和复杂,但我怀疑这是一种你经常运行的程序

答案 1 :(得分:2)

SQL更多的是关于而不是

如果您正在讨论删除c为null的行,请使用:

delete from table1 where c is null

如果您正在讨论当该列的所有行都为空时删除列,我会找到一个时间,您可以从用户锁定数据库并执行以下操作之一:

select c from table1 group by c
select distinct c from table1
select count(c) from table1 where c is not null

然后,如果你只返回NULL(或最后一个为0),编织你的魔法(SQL Server命令可能不同):

alter table table1 drop column c

为您想要的任何列执行此操作。

如果你要删除列,你真的需要小心。尽管它们可能充满了空值,但可能存在使用该列的SQL查询。删除列会破坏这些查询。

答案 2 :(得分:2)

如何检测给定列是否只有NULL值:

SELECT 1  -- no GROUP BY therefore use a literal
  FROM Locations
HAVING COUNT(a) = 0 
       AND COUNT(*) > 0;

结果集将由零行组成(列a具有非NULL值)或一行(列a仅具有NULL值)。 FWIW此代码是标准SQL-92。

答案 3 :(得分:1)

SELECT * FROM table1 WHERE c IS NOT NULL  -- or also SELECT COUNT(*)

要检测此列是否确实没有值。

ALTER TABLE table1 DROP COLUMN c
如果认为需要,

是删除列的查询。

答案 4 :(得分:1)

尝试使用您的表名作为输入的此存储过程。

alter proc USP_DropEmptyColumns 

@TableName varchar(255)
as
begin

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 = @TableName

OPEN getinfo

FETCH NEXT FROM getinfo into @col

WHILE @@FETCH_STATUS = 0
BEGIN
    SELECT @cmd = 'IF NOT EXISTS (SELECT top 1 * FROM [' + @TableName + '] WHERE [' + @col + '] IS NOT NULL) 

                        BEGIN 
                        ALTER TABLE [' + @TableName + ']  DROP Column [' + @col + ']
                        end'
    EXEC(@cmd)

    FETCH NEXT FROM getinfo into @col
END

CLOSE getinfo
DEALLOCATE getinfo

end

答案 5 :(得分:0)

PROC PRINT DATA=TABLE1;RUN;

PROC TRANSPOSE DATA=TABLE1 OUT=TRANS1;VAR A B C D E;RUN;

DATA TRANS2;SET TRANS1;IF COL1 = . AND COL2 = . THEN DELETE;RUN;

PROC TRANSPOSE DATA=TRANS2 OUT=TABLE2 (DROP=_NAME_);VAR COL1-COL2;RUN;

PROC PRINT DATA=TABLE2;RUN;