2011-01-07 20 views
6

मेरे पास बहुत सारे कॉलम और एक प्रकार कॉलम वाला एक टेबल है।ओरेकल: केवल शून्य मानों के साथ कॉलम ढूंढना

कुछ कॉलम हमेशा एक विशिष्ट प्रकार के लिए खाली लगते हैं।

मैं प्रत्येक प्रकार के लिए एक दृश्य बनाना चाहता हूं और केवल प्रत्येक प्रकार के लिए प्रासंगिक कॉलम दिखाना चाहता हूं। धारणा के तहत काम करना कि यदि किसी कॉलम के पास केवल एक विशिष्ट प्रकार के लिए शून्य मान हैं, तो उस कॉलम को दृश्य का हिस्सा नहीं होना चाहिए, आप इसे प्रश्नों के साथ कैसे ढूंढ सकते हैं?

क्या कोई का चयन करें [columnName] [तालिका] जहां [columnValues] सभी [अमान्य]

मैं जानता हूँ कि मैं पूरी तरह से सब से ऊपर बना रहे हैं ... मैं सिर्फ विचार प्राप्त करने की कोशिश कर रहा हूँ भर में। अग्रिम धन्यवाद!

+0

ऐसा नहीं है से, आप एक प्रश्न चाहते हैं कि केवल वापसी 40 कॉलम जिनमें वास्तव में डेटा है? और संभवतः अगर किसी अन्य 10 में से कोई एक मूल्य प्राप्त करता है, तो आपकी क्वेरी 41 कॉलम लौटाएगी? – MartW

+0

ऐसा लगता है कि आपके पास एक ही तालिका में रिकॉर्ड्स के विभिन्न "प्रकार" या "प्रकार" हैं, जहां आप प्रत्येक के लिए एक अलग दृश्य देखना चाहते हैं। क्या कोई कॉलम है जो रिकॉर्ड के "प्रकार" को पहचानता है? –

+0

हां यह सही @CodeByMoonlight है। –

उत्तर

0

ऐसा कुछ?

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

जाहिर है, आप उपयोग कर सकते हैं कि एक CREATE VIEW... बयान में यदि आप के रूप में अच्छी तरह।

+1

इस तथ्य के अलावा कि यह कॉलम का चयन नहीं करता है, यह तब भी नहीं बताता है जब "[columnValues] सभी [null]" होते हैं। यह पंक्तियों का एक गुच्छा चुनें जहां कुछ कॉलम (उस पंक्ति के लिए) शून्य हैं - यह निर्धारित करने के लिए उपयोगी जानकारी नहीं है कि कौन से कॉलम सभी शून्य हैं – Gerrat

+0

@Gerrat, ओरेकल की स्थिति खंड में 'सभी' कीवर्ड की कोई अवधारणा नहीं है एक 'चयन' (देखें http://download.oracle.com/docs/cd/B13789_01/server.101/b10759/conditions.htm#g1077361)। यदि @ जॉर्ज प्रत्येक 'प्रकार' के लिए अलग-अलग विचार बनाना चाहता है तो उसे यह निर्धारित करने की आवश्यकता है कि 'प्रकार' कॉलम भेदभावकर्ता पर आधारित है या उस प्रकार के सभी रिकॉर्ड्स के लिए विशिष्ट शून्य स्तंभों की उपस्थिति से। वह दो तरीकों को भ्रमित कर रहा है। –

+2

@BQ: यह एक रहस्यवादी 'ALL' कीवर्ड के बारे में नहीं है। यह ओपी क्या प्राप्त करने की कोशिश कर रहा है के बारे में है। मुझे लगता है कि यदि आप जो खोज रहे हैं उसे फिर से पढ़ते हैं, तो यह संदर्भ से बहुत स्पष्ट है कि वह बाद में क्या है: "मुझे कॉलम के कॉलम नाम दें जिसके लिए उस कॉलम की हर पंक्ति एक विशेष प्रकार के लिए शून्य है।" ... इसलिए आपकी एसक्यूएल कॉलम नामों की बजाय पंक्तियां लौटाती है, और जो पंक्तियां देता है वह वास्तव में हमें यह जानने के करीब नहीं मिलता है कि उस कॉलम के लिए प्रत्येक पंक्ति न्यूल है। यह बस पंक्तियों को वापस कर रहा है जहां (कॉलम के दिए गए सेट में प्रत्येक कॉलम) शून्य – Gerrat

0

@Gerrat और @ बीक्यू की टिप्पणियों को देखने के बाद, मैं आपको निम्न तरीके से आवश्यक विवरण प्राप्त कर सकता हूं: मेरे पास एक विरासत तालिका है जिसमें एन अलग-अलग प्रकार हैं। सभी प्रकार कॉलम साझा करते हैं, और विशिष्ट कॉलम होते हैं।

मैं सभी कॉलम के साथ प्रत्येक प्रकार के लिए एक दृश्य बना सकता हूं, फिर सभी कॉलम नाम प्राप्त करने के लिए all_tab_columns का उपयोग करें जहां "num_nulls" उस विशिष्ट प्रकार के पंक्तियों की कुल संख्या से कम है।

वहां से कॉलम इकट्ठा करना आसान होना चाहिए जो प्रत्येक प्रकार के लिए उपयोग किए जाते हैं और विचार बनाते हैं।

विचार?

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

रिटर्न कैसे स्तंभ प्रति कई रिकॉर्ड एक गैर शून्य मान है (कम से कम Oracle में, कि है।)

उदाहरण के लिए

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; 

रिटर्न

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

यह दर्शाता है कि col_3 में केवल nulls होते हैं।

इस विचार का उपयोग वांछित दृश्य बनाने के लिए किया जा सकता है।

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; 

कौन सा, जब चयनित रिटर्न:

तालिका अब भी * group_id * जरूरत

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

यह मानक एसक्यूएल है, न सिर्फ ओरेकल। आप यह भी कर सकते हैं: 'चुनें COUNT (col_1), COUNT (col_2), COUNT (col_3) [...] कुछटेबल हैविंग COUNT (*)> 0 और (COUNT (col_1) = 0 या COUNT (col_2) = 0 या COUNT (col_3) = 0' से। यह सभी खाली तालिकाओं को अनदेखा करता है और परीक्षण में से कम से कम एक परीक्षण करता है कॉलम में केवल नल हैं। –

+0

मेरी तालिका में 300 से अधिक कॉलम हैं। मैं प्रत्येक 300 बार गिनना नहीं चाहता हूं। –

+0

मुझे अपनी मूल तालिका से कोई रिकॉर्ड नहीं चाहिए। मुझे जो चाहिए वह कॉलम नामों की एक सूची है मेरी तालिका जहां किसी विशिष्ट प्रकार के सभी रिकॉर्ड्स में केवल शून्य मान होते हैं। –

0

मुझे लगता है कि आप इस metaprogramming का उपयोग कर हल कर सकते हैं। प्रत्येक प्रकार और कॉलम के माध्यम से लूप के लिए एक कर्सर का उपयोग करें, और कॉलम खाली है या नहीं, यह जांचने के लिए 'मौजूद नहीं है' का उपयोग करें। उदाहरण के लिए:

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 

क्षमा याचना वहाँ कहीं वाक्य रचना में कोई गलती है, तो, मैं इस पर जांच करने के लिए कुछ भी नहीं है।

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

मुझे आंकड़े पहले 'DBMS_STATS.gather_database_stats();' चलाते थे; और फिर यह एक आकर्षण की तरह काम करता था! धन्यवाद;) – nathanvda

0

चयन tablecolumn, tablecolumn2, ... TableName जहां स्तंभ अगर आप 50 कॉलम हैं, और उनमें से 10 केवल शून्य मान हैं शून्य

संबंधित मुद्दे