Sql 如何检测和删除只包含空值的列?
在我的表格表格1中有6列位置,a、b、c、d、eSql 如何检测和删除只包含空值的列?,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查询检测
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;