2012-10-22 20 views
5

Znalazłem DB, który ma tabele, które są zbyt szerokie. (Ponad 600 kolumn) Nawet pytanie o 100 najlepszych wierszy bez parametrów zajmuje 4 sekundy. Chciałbym schudnąć te stoły.Policz liczbę wartości zerowych w każdej kolumnie

Aby dowiedzieć się, które kolumny mogą być najłatwiej przeniesione do nowych tabel lub całkowicie usunięte, chciałbym wiedzieć, ile wartości zerowych są w każdej kolumnie. To powinno mi powiedzieć, jakie informacje mogą być najmniej ważne.

Jak napisać zapytanie, które może znaleźć wszystkie kolumny i policzyć wartości null wewnątrz tych kolumn?

Edit DB jest serwer SQL 2008. Jestem naprawdę nadzieję nie wpisywać każdej kolumny osobno. Wygląda na to, że sys.columns może w tym pomóc?

Edit2 Wszystkie kolumny mają różne typy.

+2

np chcesz znaleźć kolumny, które są zerowe, więc możesz je po prostu upuścić? bolesne, ale 'select count (*) from sometable when somecolumn is null' one-at-a-time zrobi lew. –

+0

Czy wszystkie kolumny mają ten sam typ danych? –

+0

Nie są tego samego typu. Dane są bardzo niedopasowane, wahają się od numerów licencji kierowców do pól adresowych, do wartości pieniężnych, do "złożonych obietnic", cokolwiek to jest. – Drigan

Odpowiedz

6

Spróbuj

declare @Table_Name nvarchar(max), @Columns nvarchar(max), @stmt nvarchar(max) 

declare table_cursor cursor local fast_forward for 
    select 
     s.name, 
     stuff(
      (
       select 
        ', count(case when ' + name + 
        ' is null then 1 else null end) as count_' + name 
       from sys.columns as c 
       where c.object_id = s.object_id 
       for xml path(''), type 
      ).value('data(.)', 'nvarchar(max)') 
     , 1, 2, '') 
    from sys.tables as s 

open table_cursor 
fetch table_cursor into @Table_Name, @Columns 

while @@FETCH_STATUS = 0 
begin 
    select @stmt = 'select ''' + @Table_Name + ''' as Table_Name, ' + @Columns + ' from ' + @Table_Name 

    exec sp_executesql 
     @stmt = @stmt 

    fetch table_cursor into @Table_Name, @Columns 
end 

close table_cursor 
deallocate table_cursor 
+0

Zajmuje mi trochę czasu, aby owinąć mi głowę tym, co tam zrobiłeś, ale do tej pory wygląda dobrze. :) – Drigan

+0

Teraz, gdy to rozumiem, to jest niesamowite! Dziękuję Ci! – Drigan

2
select count(case when Column1 is null then 1 end) as Column1NullCount, 
    count(case when Column2 is null then 1 end) as Column2NullCount, 
    count(case when Column3 is null then 1 end) as Column3NullCount, 
    ... 
from MyTable 
+0

Mam * naprawdę * nadzieję, że unikam pisania w 688 kolumnach pojedynczo. . . może sys.columns będzie użyteczny? – Drigan

+0

Po co pisać? Powinno być proste uzyskanie nazw kolumn (np. 'Wybierz * z MyTable gdzie 1 = 0'), w zależności od bazy danych. Następnie jest trochę pracy edytora tekstów, aby to zrobić. Prawdopodobnie szybciej niż pisanie zapytania dynamicznego, aby to zrobić. – RedFilter

+0

Sądzę, że mam nadzieję na nieco więcej elegancji, ponieważ istnieje kilka tabel, które mają ponad 100 kolumn. Nie koniec świata, jeśli go nie mam, ale to * zajmie trochę więcej czasu. – Drigan

Powiązane problemy