Найти столбцы, содержащие только нули - PullRequest
5 голосов
/ 02 марта 2012

Я работаю с SQL Server 2008. У меня есть список имен столбцов в таблице, и я хотел бы знать, как использовать SQL для возврата имен тех столбцов, которые содержат только нулевые или нулевые значения.

Ответы [ 3 ]

3 голосов
/ 03 марта 2012
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.

2 голосов
/ 03 марта 2012

Это грубый метод, так как вы знаете все имена столбцов.

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 и удалив столбцы, которые не нужны вручную).

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 и запрос ...

0 голосов
/ 03 марта 2012

Вот способ, который работает для любой таблицы:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...