Bu aslında bir çapraz iş (veya diğer RDBMS'de "pivot") değil, tersi işlem ise, bir karşı-çaprazlama yaparsanız. Bir zarif teknik, LATERAL
birleşiminde bir VALUES
ifadesidir.
SELECT c.col, c.ct
FROM (
SELECT count(col1 OR NULL) AS col1
, count(col2 OR NULL) AS col2
-- etc.
FROM tbl
) t
, LATERAL (
VALUES ('col1', col1)
, ('col2', col2)
-- etc.
) c(col, ct)
ORDER BY 2
Bu basit kısımdı. Öteki isteği zordur:
- el sütunları
Bu fonksiyon, tablo adını alır ve sistem katalog pg_attribute
meta verileri alır adlarını yazmak zorunda.
CREATE OR REPLACE FUNCTION f_true_ct(_tbl regclass)
RETURNS TABLE (col text, ct bigint) AS
$func$
BEGIN
RETURN QUERY EXECUTE (
SELECT format('
SELECT c.col, c.ct
FROM (SELECT %s FROM tbl) t
, LATERAL (VALUES %s) c(col, ct)
ORDER BY 2 DESC'
, string_agg (format('count(%1$I OR NULL) AS %1$I', attname), ', ')
, string_agg (format('(%1$L, %1$I)', attname), ', ')
)
FROM pg_attribute
WHERE attrelid = _tbl -- valid, visible, legal table name
AND attnum >= 1 -- exclude tableoid & friends
AND NOT attisdropped -- exclude dropped columns
AND atttypid = 'bool'::regtype -- only character types
);
END
$func$ LANGUAGE plpgsql;
Çağrı:
SELECT * FROM f_true_ct('tbl'); -- table name optionally schema-qualified
Sonuç:
col | ct
------+---
col1 | 3
col3 | 2
col2 | 1
İşleri tüm sıralamak için herhangi tablo için SQL enjeksiyonu karşı güvenli yukarıdaki sorgu dinamik uygulanması, var boolean
sütunlarına göre true
değerleri.
fonksiyon parametresini anlamak için, bu okuyun:
İlgili cevaplar daha açıklama ile:
Muhtemelen 'crosstab' onu ele alacaktır. Lütfen http://sqlfiddle.com örnek verilerini sağlayın ve istenen resultset – lad2025
@ lad2025 'crosstab' ile de sütunların isimlerini elle yazmak zorundasınız. Temel olarak, OP'nin sunumuyla (sonuç açısından) işleyiş ile aynı olan bir dinamik ifade kullanmıyorsanız –
Sorunuzu düzenleyin ve istediğiniz resulleri sağlayın –