Find columns that contain only zeros

有些话、适合烂在心里 提交于 2021-02-07 14:18:27

问题


I'm working with SQL Server 2008. I have a list of column names on a table and I'd like to know how to use SQL to return the names of those columns which contain nothing but zero or NULL values.


回答1:


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

Result:

ColName
----------
Col2
Col3

The idea behind this is to count the non null values and only keep those with a count of 0.

COUNT will only count non null values.
NULLIF(ColX, 0) will make all 0 into null.
The inner query returns one row with four columns. UNPIVOT will turn it around so you have two columns and four rows.
Finally where U.C = 0 makes sure that you only get the columns that has no values other than null or 0.




回答2:


Here is a brute force way, since you know all the column names.

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;

You could probably generate much of this script instead of doing it manually, assuming you know the naming scheme or data type of the columns you want (or just by leaving off the where clause entirely and removing the columns you don't want manually).

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%'
;

The output will look like the middle of the first query, so you can copy & paste and then remove the first + and add the surrounding STUFF and query...




回答3:


Here's a way that works for any table:

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


来源:https://stackoverflow.com/questions/9539084/find-columns-that-contain-only-zeros

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!