问题
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