2012-12-07 40 views
5

मेरे पास एन कॉलम के साथ एक तालिका है। आइए उन्हें c1, c2, c3, c4, ... cN पर कॉल करें। कई पंक्तियों में से, मैं प्रत्येक एक्स के लिए [1, एन] में COUNT DISTINCT(cX) के साथ एक पंक्ति प्राप्त करना चाहता हूं।कॉलम सूचीबद्ध किए बिना, प्रत्येक कॉलम पर समान एकत्रीकरण कैसे करें?

c1 | c2 | ... | cn 
0 | 4 | ... | 1 

क्या कोई तरीका है कि मैं इसे प्रत्येक कॉलम नाम मैन्युअल रूप से क्वेरी में लिखने के बिना (संग्रहीत प्रक्रिया में) कर सकता हूं?

क्यों?

हमें एक समस्या है जहां एप्लिकेशन सर्वर में कीड़े का मतलब है कि हम बाद में कचरे के साथ अच्छे कॉलम मानों को फिर से लिखते हैं। इसे हल करने के लिए, मैं सूचना लॉग-संरचना संग्रहीत कर रहा हूं, जहां प्रत्येक पंक्ति तार्किक UPDATE क्वेरी का प्रतिनिधित्व करती है। फिर, जब एक संकेत दिया गया कि रिकॉर्ड पूरा हो गया है, तो मैं यह निर्धारित कर सकता हूं कि कोई मान (गलती से) ओवरराइट किया गया था या नहीं।

एकाधिक पंक्तियों में एक एकल सही रिकॉर्ड का एक उदाहरण: प्रत्येक कॉलम के लिए अधिकतम एक मूल्य है।

| id | initialize_time | start_time | end_time | 
| 1 | 12:00am   | NULL  | NULL  | 
| 1 | 12:00am   | 1:00pm  | NULL  | 
| 1 | 12:00am   | NULL  | 2:00pm | 

Reconciled row: 
| 1 | 12:00am   | 1:00pm  | 2:00pm | 

एक कट्टर विरोधी रिकॉर्ड है कि मैं पता लगाने के लिए चाहते हैं का एक उदाहरण:

| id | initialize_time | start_time | end_time | 
| 1 | 12:00am   | NULL  | NULL  | 
| 1 | 12:00am   | 1:00pm  | NULL  | 
| 1 | 9:00am   | 1:00pm  | 2:00pm | -- New initialize time => irreconcilable! 
+0

क्या आप कॉलम नाम लाने के लिए पूछ रहे हैं, या एकत्रीकरण कैसे करें? –

+0

मुझे पता है कि कॉलम नाम कैसे प्राप्त करें, लेकिन मुझे नहीं पता कि क्वेरी में प्रत्येक कॉलम नाम के चारों ओर एक अभिव्यक्ति का विस्तार करने के लिए क्या करना है। मैं अपनी संग्रहित प्रक्रिया में 'SELECT COUNT DISTINCT (c1), COUNT DISTINCT (c2), ..., COUNT DISTINCT (cN) से बचना चाहता हूं ... ' –

+0

आप इसे गतिशील एसक्यूएल के साथ कर सकते हैं। वैसे, एक्स कितना बड़ा है? – dezso

उत्तर

3

आप उस के लिए गतिशील एसक्यूएल, जिसका मतलब है कि आप एक समारोह बना सकते हैं या एक DO आदेश को चलाने के लिए है की जरूरत है। जब से तुम बाद से सीधे मान नहीं कर सकते, एक plpgsql समारोह यह है:

CREATE OR REPLACE function f_count_all(_tbl text 
          , OUT columns text[], OUT counts bigint[]) 
    RETURNS record LANGUAGE plpgsql AS 
$func$ 
BEGIN 

EXECUTE (
    SELECT 'SELECT 
    ARRAY[' || string_agg('''' || quote_ident(attname) || '''', ', ') || '], 
    ARRAY[' || string_agg('count(' || quote_ident(attname) || ')', ', ') || '] 
    FROM ' || _tbl 
    FROM pg_attribute 
    WHERE attrelid = _tbl::regclass 
    AND attnum >= 1   -- exclude tableoid & friends (neg. attnum) 
    AND attisdropped is FALSE -- exclude deleted columns 
    GROUP BY attrelid 
    ) 
INTO columns, counts; 

END 
$func$; 

कॉल:

SELECT * FROM f_count_all('myschema.mytable'); 

रिटर्न:

columns  | counts 
--------------+-------- 
{c1, c2, c3,} | {17 1,0} 

अधिक विवरण और गतिशील एसक्यूएल के बारे में लिंक और EXECUTEthis related question में - या SO, try this serach पर यहां कुछ और अधिक।

बहुत इस सवाल के समान:
postgresql - count (no null values) of each column in a table

तुम भी कोशिश करते हैं और एक कॉलम गतिशील प्राप्त करने के लिए एक बहुरूपी रिकॉर्ड प्रकार लौट सकता है, लेकिन है कि जटिल और उन्नत है। शायद आपके मामले के लिए बहुत अधिक प्रयास। this related answer में और अधिक।