2012-12-07 32 views
5

N sütunlarına sahip bir tablom var. Bunları c1, c2, c3, c4, ... cN olarak adlandıralım. Birden çok satır arasında, [1, N] 'de her X için COUNT DISTINCT(cX) ile tek bir satır almak istiyorum.Sütunları listelemeden her bir sütunda aynı birleştirme nasıl yapılır?

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

Bunu yapmanın bir yolu elle sorgusuna içine her sütun adını yazmadan (bir saklı yordam olarak) var mı?

Neden?

Uygulama sunucularındaki hataların, daha sonra eklenen çöplerle birlikte iyi sütun değerlerini yeniden yazmamız anlamına geldiği bir sorun yaşadık. Bunu çözmek için, her satırın mantıksal bir UPDATE sorgusunu temsil ettiği bilgi günlük yapısını saklıyorum. Daha sonra, kaydın tamamlandığını gösteren bir sinyal verildiğinde, herhangi bir değerin (hatalı olarak) üzerine yazılıp yazılmadığını belirleyebilirim.

Birden çok satırda tek bir doğru kayıt örneği: her sütun için en fazla bir değer vardır.

| 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 | 

Ben algılamak istiyorum uzlaşmaz bir kaydın bir örneği:

| 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

Sütun adlarını veya toplama işlemini nasıl yapacağınızı mı soruyorsunuz? –

+0

Sütun adlarını nasıl getireceğimi biliyorum, ancak sorgudaki her sütun adına ilişkin bir ifadeyi genişletmek için ne yapacağımı bilmiyorum. Ben, 'SELECT COUNT DISTINCT (c1) önlemek DISTINCT COUNT istiyorum (c2), ..., İTİBAREN (cN) DISTINCT COUNT ...' benim saklı yordam içinde. –

+0

Bunu elbette dinamik SQL ile yapabilirsiniz. Bu arada, X ne kadar büyük? – dezso

cevap

3

Sen bir işlev oluşturmak veya DO komutu çalıştırmak zorunda olduğu anlamına gelir için dinamik SQL, gerekir. Eğer ikincisi doğrudan değerleri döndüremez beri bir plpgsql fonksiyonu öyle:

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$; 

Çağrı:

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

İade:

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

fazla açıklama ve dinamik SQL hakkında linkler ve this related question numaralı telefondan EXECUTE - ya da bir çift burada SO, try this serach. Bu soruya çok benzer

:
postgresql - count (no null values) of each column in a table

Hatta denemek ve dinamik tek sütun almak için bir polimorfik rekor türü dönmek, ama bu oldukça karmaşık ve gelişmiş şu şekilde. Davanız için muhtemelen çok fazla çaba. Daha fazla this related answer.

İlgili konular