2011-01-07 14 views
6

Çok fazla sütun ve bir sütun içeren bir tablom var.Oracle: Yalnızca null değerlerle sütun bulma

Bazı sütunlar belirli bir tür için her zaman boş görünüyor.

Her tür için bir görünüm oluşturmak ve yalnızca her tür için ilgili sütunları göstermek istiyorum. Bir sütun belirli bir tür için SADECE boş değerler içeriyorsa, o sütunların görünümün bir parçası olmaması gerektiği varsayımı altında çalışarak, bunları sorgularla nasıl bulabilirsin?

mi orada SEÇ [columnName] DAN [tablo] NEREDE [columnValues] TÜM [boş]

biliyorum ben TAMAMEN ben sadece fikir almaya çalışıyorum ... Yukarıda hepsini oluşur ARE karşısında. Şimdiden teşekkürler!

+0

Yani IS NOT NULL tabloismi İTİBAREN, bir sorguyla istediğiniz sadece olacak dönüş Aslında veri içeren 40 sütun? Ve eğer diğer 10'dan biri bir değer elde ederse, sorgunuz daha sonra 41 sütun döndürecek? – MartW

+0

Aynı tabloda, her biri için ayrı bir görünüme sahip olmak istediğiniz farklı "tür" veya "tür" kayıtlarınız var gibi görünüyor. Kaydın "türünü" tanımlayan bir sütun var mı? –

+0

Evet, bu doğru @CodeByMoonlight. –

cevap

0

Böyle bir şey mi var? siz de isterseniz

SELECT column1, column2, column3 -- and so on 
FROM tableA 
WHERE columnX IS NULL 
AND columnY IS NULL 
AND columnZ IS NULL; 

Açıkçası, bir CREATE VIEW... açıklamada kullanabiliriz.

+1

Bunun sütunları seçmemesinin yanı sıra, bu "[columnValues] ALL [null]" olduğunda bile bir şey ifade etmiyor. Bu, belirli sütunların (bu satır için) null olduğu bir satır satırı seçecektir - bu, hangi sütunların boş olduğunu belirlemek için yararlı bilgiler değildir. – Gerrat

+0

@Gerrat, Oracle'ın "ALL" anahtar sözcüğünün koşulunun tümcesi 'SELECT' (bkz. http://download.oracle.com/docs/cd/B13789_01/server.101/b10759/conditions.htm#g1077361). Eğer Jorge, her 'tip' için farklı görünümler oluşturmak istiyorsa, 'tip'in bir sütun ayırımcısına mı yoksa o türdeki tüm kayıtlar için belirli boş sütunların bulunup bulunmadığına karar vermesi gerekir. İki yöntemi karıştırıyor gibi görünüyor. –

+2

@BQ: Bu bir mistik "ALL" anahtar kelimesiyle ilgili değil. OP'nin almaya çalıştığı şeyle ilgili. Eğer aradığı şeyi tekrar okursanız, temelde şu anki durumun temel olarak ne olduğu açıkça anlaşılır: "Bana bu sütunun HER sırasının, belirli bir tür için boş olduğu sütunların sütun adlarını verin." ... böylece sql'niz sütun isimleri yerine satırlar döndürür ve verdiği satırlar, bu sütun için HER satırın NULL olup olmadığını bilmemize daha fazla yaklaşmaz. Basitçe satırları döndürüyor (belirli bir sütun kümesindeki her sütun) NULL – Gerrat

0

@Gerrat ve @ BQ adlı yorumlarına baktıktan sonra, ihtiyacım olan ayrıntıları şu şekilde alabilirim: N farklı türden bir eski tablo var. Tüm türler sütunları paylaşır ve özel sütunlara sahiptir.

Tüm sütunlara sahip her tür için bir görünüm oluşturabilir, daha sonra "num_nulls" ifadesinin bu belirli türdeki toplam satır sayısından daha az olduğu tüm sütun adlarını almak için all_tab_columns kullanın.

Buradan, her tür için kullanılan sütunları toplamak ve görünümleri oluşturmak kolay olmalıdır.

Düşünceler? Sütun başına çok sayıda kayıt boş olmayan bir değere sahip nasıl

2
select 
    count(col_1), 
    count(col_2), 
    count(col_3) 
from 
    <table> 

döner (en azından Oracle, yani.) Örneğin

drop table tq84_count_nulls; 

create table tq84_count_nulls (
    col_1 varchar(50), 
    col_2 number, 
    col_3 date 
); 

insert into tq84_count_nulls values (null, null, null); 
insert into tq84_count_nulls values ('xx', null, null); 
insert into tq84_count_nulls values (null, 42, null); 
insert into tq84_count_nulls values ('yy', 12, null); 

select 
    count(col_1), 
    count(col_2), 
    count(col_3) 
from 
    tq84_count_nulls; 

döner

COUNT(COL_1) COUNT(COL_2) COUNT(COL_3) 
------------ ------------ ------------ 
      2   2   0 

col_3 öğesinin yalnızca sıfırlardan oluştuğunu belirten.

Bu fikir, istenen görünümü oluşturmak için kullanılabilir. döner seçildiğinde

drop table tq84_count_nulls; 
create table tq84_count_nulls (
    col_1 varchar(50), 
    col_2 number, 
    col_3 date, 
    group_id varchar(2) 
); 

insert into tq84_count_nulls values (null, null, null, 'a'); 
insert into tq84_count_nulls values ('xx', null, null, 'a'); 
insert into tq84_count_nulls values (null, 42, null, 'a'); 
insert into tq84_count_nulls values ('yy', 12, null, 'a'); 

insert into tq84_count_nulls values (null, null, null, 'b'); 
insert into tq84_count_nulls values (null, null, null, 'b'); 
insert into tq84_count_nulls values (null, 42, null, 'b'); 
insert into tq84_count_nulls values (null, 12, null, 'b'); 




create or replace view nulls_per_type as 
with n as (
    select 
    count(col_1) col_1_count, 
    count(col_2) col_2_count, 
    count(col_3) col_3_count, 
    group_id 
    from 
    tq84_count_nulls 
    group by 
    group_id 
), 
o as (
select case col_1_count when 0 then 'COL_1 is always 0 for ' || group_id else null end u from n union all 
select case col_2_count when 0 then 'COL_2 is always 0 for ' || group_id else null end u from n union all 
select case col_3_count when 0 then 'COL_3 is always 0 for ' || group_id else null end u from n 
) 
select * from o where u is not null; 

hangisi,:

tablo şimdi de * group_id * ihtiyacı

select * from nulls_per_type; 

COL_1 is always 0 for b 
COL_3 is always 0 for a 
COL_3 is always 0 for b 
+0

Bu yalnızca SQL değil, standart SQL'dir. Ayrıca: 'SELECT COUNT (col_1), COUNT (col_2), COUNT (col_3) [...] BazıTable HAVING COUNT (*)> 0 AND (COUNT (col_1) = 0 OR COUNT (col_2) = 0 VEYA COUNT (col_3) = 0'DAN .Bu tüm boş tabloları yok sayar ve yalnızca testlerden en az biri varsa herhangi bir şey döndürür sütunlar içinde sadece null vardır –

+0

Benim tablo 300'den fazla sütun var.Ben 300 kez saymak istemiyorum –

+0

Benim orijinal tablodan herhangi bir kayıt istemiyorum. İhtiyacım olan sütun isimleri listesi belirli bir tür için tüm kayıtların yalnızca boş değerlere sahip olduğu tablomda –

0

Bunu kullanarak metaprogramming çözebilir düşünüyorum. Her tür ve sütunda dolaşmak için bir imleç kullanın ve sütunun boş olup olmadığını kontrol etmek için 'mevcut' seçeneğini kullanın. Örneğin:

CREATE TABLE result_table (type VARCHAR(50), column VARCHAR(50)) 

CURSOR c IS 
    SELECT COLUMN_NAME FROM ALL_TAB_COLS WHERE TABLE_NAME = &table_name; 

CURSOR ct IS 
    SELECT DISTINCT type_name FROM &table_name; 

BEGIN 

FOR t in ct 
LOOP 
    FOR r in c 
    LOOP 
     --If you're confused about how this works, replace 'EXECUTE IMMEDIATE' 
     --with print or something and look at the output 
     EXECUTE IMMEDIATE 
      'INSERT INTO result_table SELECT ''' || 
       t.type_name || ''', ''' || r.COLUMN_NAME || 
       ''' FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM ' || 
       &table_name || ' WHERE t.type_name = ''' || t.type_name || 
       ''' AND ' || r.COLUMN_NAME || ' IS NOT NULL);'; 
    END LOOP 
END LOOP 

SELECT * FROM result_table 

Özür yere sözdiziminde bir hata varsa, bu konuda kontrol etmek hiçbir şey yok.

9
SELECT t.column_name 
FROM user_tab_columns t 
WHERE t.nullable = 'Y' 
     AND t.table_name = 'YOUR_TABLE_NAME' 
     AND t.num_distinct = 0 
+1

İlk önce istatistikleri çalıştırmam gerekiyordu 'DBMS_STATS.gather_database_stats();' ve sonra bu bir çekicilik gibi çalıştı! Teşekkürler;) – nathanvda

0

SEÇ tablecolumn, tablecolumn2 ... 50 sütun var ve bunlardan 10 sadece NULL değerleri içeriyorsa sütun

İlgili konular