2012-03-02 3 views
4

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

+1

Я предполагаю, что вы хотите автоматизированный способ, не зная названия столбцов? – JNK

+0

было бы неплохо, но я знаю имена столбцов. – Brownie

+0

Возможный дубликат [SQL: выберите столбцы только с значениями NULL] (http://stackoverflow.com/questions/63291/sql-select-columns-with-null-values-only) – genpfault

ответ

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; 

Вы могли бы генерировать большую часть этого сценария вместо того, чтобы делать это вручную, если вы знаете схему именования или тип данных столбцов, которые вы хотите (или просто убрав где положение полностью и удаление столбцов вам не хочет вручную).

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

Это был не я, но ваш запрос не удался, когда я попробовал. – Phil

+0

Что означает «провал»? Неверный ответ? Сообщение об ошибке? Если сообщение об ошибке, что это такое? Используете ли вы SQL Server 2008 в качестве исходного плаката? –

+0

Моя ошибка, она работает нормально. – Phil

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', @[email protected] 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 
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.

+0

+1 умный. Но, возможно, это слишком умно для большинства пользователей. :-) –

Смежные вопросы