Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何检测和删除只包含空值的列?_Sql_Sql Server 2005 - Fatal编程技术网

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

Sql 如何检测和删除只包含空值的列?,sql,sql-server-2005,Sql,Sql Server 2005,在我的表格表格1中有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查询检测

在我的表格表格1中有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查询检测和删除包含所有空值的列。 可能吗

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

SELECT * FROM table1 WHERE c IS NOT NULL  -- or also SELECT COUNT(*)
检测此列是否确实没有任何值

ALTER TABLE table1 DROP COLUMN c

如果认为需要,则是删除列的查询。

SQL更多的是处理行而不是列

如果要删除c为空的行,请使用:

delete from table1 where c is null
如果您要在所有行都为空的情况下删除某个列,我只想找到一个时间,您可以从用户那里锁定DB并执行以下操作之一:

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命令可能不同):

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

如果要删除列,确实需要小心。即使它们可能满是null,也可能有使用该列的SQL查询。删除列将中断这些查询。

这里有一个快速(且难看)的存储过程,它采用表名并打印(如果需要,也可以删除)满是空值的字段

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

这使用了一个游标,速度有点慢,有点复杂,但我怀疑这是一种您经常运行的过程

如何检测给定列是否只有
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。

请使用表名作为输入,尝试此存储过程。
要做到这一点,您需要大量的数据定义代码和自定义服务器语法。如果你能说出table1将是什么数据库平台,那会很有帮助。我想知道你为什么要这么做……呃,@SWeko,SQL Server 2005不是DBMS吗?现在我觉得有点傻:)我知道这很老了,但对于任何偶然发现这一点的人来说,还值得引用列名和表名。我建议添加额外的解释,说明这是如何解决原始问题的,以及为什么您认为这是最好的方法,而不是简单地提供脚本。
SELECT 1  -- no GROUP BY therefore use a literal
  FROM Locations
HAVING COUNT(a) = 0 
       AND COUNT(*) > 0;
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
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;