查找仅包含零的列

时间:2012-03-02 19:19:13

标签: sql sql-server sql-server-2008

我正在使用SQL Server 2008.我在表上有一个列名列表,我想知道如何使用SQL返回那些只包含零或NULL值的列的名称。 / p>

3 个答案:

答案 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确保您只获得没有null0以外的值的列。

答案 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