我正在使用SQL Server 2008.我在表上有一个列名列表,我想知道如何使用SQL返回那些只包含零或NULL值的列的名称。 / p>
答案 0 :(得分:3)
declare @T table
(
Col1 int,
Col2 int,
Col3 int,
Col4 int
)
insert into @T values
(1, 0 , null, null),
(0, null, 0 , 1)
select U.ColName
from
(
select count(nullif(Col1, 0)) as Col1,
count(nullif(Col2, 0)) as Col2,
count(nullif(Col3, 0)) as Col3,
count(nullif(Col4, 0)) as Col4
from @T
) as T
unpivot
(C for ColName in (Col1, Col2, Col3, Col4)) as U
where U.C = 0
结果:
ColName
----------
Col2
Col3
这背后的想法是计算非null
值并仅保留计数为0
的值。
COUNT只计算非空值
NULLIF(ColX, 0)会将所有0
变为null
内部查询返回一行有四列。 UNPIVOT会将其翻转,因此您有两列四行
最后where U.C = 0
确保您只获得没有null
或0
以外的值的列。
答案 1 :(得分:1)
这是一种蛮力方式,因为您知道所有列名称。
CREATE TABLE dbo.splunge
(
a INT,
b INT,
c INT,
d INT
);
INSERT dbo.splunge VALUES (0,0,1,-1), (0,NULL,0,0), (0,0,0,NULL);
SELECT
cols = STUFF(
CASE WHEN MIN(COALESCE(a,0)) = MAX(COALESCE(a,0)) THEN ',a' ELSE '' END
+ CASE WHEN MIN(COALESCE(b,0)) = MAX(COALESCE(b,0)) THEN ',b' ELSE '' END
+ CASE WHEN MIN(COALESCE(c,0)) = MAX(COALESCE(c,0)) THEN ',c' ELSE '' END
+ CASE WHEN MIN(COALESCE(d,0)) = MAX(COALESCE(d,0)) THEN ',d' ELSE '' END,
1, 1, '')
FROM dbo.splunge;
-- result:
-- a,b
GO
DROP TABLE dbo.splunge;
您可能会生成大部分此脚本而不是手动执行此操作,假设您知道所需列的命名方案或数据类型(或者只是完全不使用where子句并删除 don 't 想手动)。
SELECT CHAR(13) + CHAR(10) + ' + CASE WHEN MIN(COALESCE(' + name + ',0)) = '
+ 'MAX(COALESCE(' + name + ',0)) THEN '',' + name + ''' ELSE '''' END'
FROM sys.columns
WHERE [object_id] = OBJECT_ID('dbo.splunge')
-- AND system_type_id = 56
-- AND name LIKE '%some pattern%'
;
输出看起来像第一个查询的中间位置,因此您可以复制&粘贴然后移除第一个+
并添加周围的STUFF
并查询...
答案 2 :(得分:0)
这是一种适用于任何表格的方式:
declare @tableName nvarchar(max) = N'myTable'
declare @columnName nvarchar(max)
create table #zeros (column_name varchar(max))
declare c cursor local forward_only read_only for
select column_name
from information_schema.COLUMNS WHERE table_name = @tableName
open c
fetch next from c into @columnName
while @@FETCH_STATUS = 0
begin
declare @retval int
declare @sql nvarchar(max) =
N'set @retval = (select count(*) from ' + @tableName + N' where coalesce(' + @columnName + N', 0) <> 0)'
exec sp_executesql @sql, N'@retval int out', @retval=@retval out
select @retval
if @retval = 0
begin
insert into #zeros (column_name) values (@columnName)
end
fetch next from c into @columnName
end
close c
deallocate c
select * from #zeros
drop table #zeros