İşlevi sağlayan ek modülütablefunc
her veritabanı için bir kez kurun crosstab()
. Postgres 9.1'den beri CREATE EXTENSION
bunun için kullanabilirsiniz :
CREATE EXTENSION IF NOT EXISTS tablefunc;
Geliştirilmiş test senaryosu
CREATE TABLE tbl (
section text
, status text
, ct integer -- "count" is a reserved word in standard SQL
);
INSERT INTO tbl VALUES
('A', 'Active', 1), ('A', 'Inactive', 2)
, ('B', 'Active', 4), ('B', 'Inactive', 5)
, ('C', 'Inactive', 7); -- ('C', 'Active') is missing
Basit form - eksik özellikler için uygun değil
crosstab(text)
ile 1 giriş parametresi:
SELECT *
FROM crosstab(
'SELECT section, status, ct
FROM tbl
ORDER BY 1,2' -- needs to be "ORDER BY 1,2" here
) AS ct ("Section" text, "Active" int, "Inactive" int);
İadeler:
Bölüm | Aktif | pasif
--------- + -------- + ----------
A | 1 | 2
B | 4 | 5
C | 7 | - !!
- Döküm ve yeniden adlandırma gerekmez.
- Şunun için yanlış sonuca dikkat edin
C
: değer 7
ilk sütun için doldurulur. Bazen, bu davranış istenir, ancak bu kullanım durumu için değil.
- Basit form ayrıca sağlanan giriş sorgusundaki tam olarak üç sütunla sınırlıdır : satır_adı , kategori , değer . Aşağıdaki 2 parametreli alternatifte olduğu gibi fazladan sütunlar için yer yoktur .
Güvenli form
crosstab(text, text)
ile 2 giriş parametreleri:
SELECT *
FROM crosstab(
'SELECT section, status, ct
FROM tbl
ORDER BY 1,2' -- could also just be "ORDER BY 1" here
, $$VALUES ('Active'::text), ('Inactive')$$
) AS ct ("Section" text, "Active" int, "Inactive" int);
İadeler:
Bölüm | Aktif | pasif
--------- + -------- + ----------
A | 1 | 2
B | 4 | 5
C | | 7 - !!
İçin doğru sonucu not edin C
.
İkinci parametre döner bir herhangi bir sorgu olabilir satır özellik başına sonunda sütun tanımının sırasını bulundu. Genellikle, temel tablodan aşağıdaki gibi farklı özellikleri sorgulamak istersiniz:
'SELECT DISTINCT attribute FROM tbl ORDER BY 1'
Bu kılavuzda.
Yine de bir sütun tanımı listesindeki tüm sütunları (önceden tanımlanmış varyantlar hariç) hecelemeniz gerektiğinden, gösterildiği gibi bir ifadede kısa bir liste sağlamak genellikle daha etkilidir :crosstabN()
VALUES
$$VALUES ('Active'::text), ('Inactive')$$)
Veya (kılavuzda değil):
$$SELECT unnest('{Active,Inactive}'::text[])$$ -- short syntax for long lists
Fiyat teklifini kolaylaştırmak için dolar fiyatını kullandım .
Değer sütununun metin gösterimi hedef tür için geçerli girdi olduğu sürece , farklı veri türlerine sahip sütunlar bile verebilirsiniz crosstab(text, text)
. Aklınıza gelebilecek Bu şekilde farklı tür ve çıkış niteliklerini text
, date
, numeric
ilgili özellikler için vs. Kılavuzdaki bölümüncrosstab(text, text)
sonunda bir kod örneği vardır .
burada keman
Gelişmiş örnekler
\crosstabview
psql'de
Postgres 9.6 bu meta komutu varsayılan interaktif terminal psql'sine ekledi . İlk crosstab()
parametre olarak kullanacağınız sorguyu çalıştırabilir ve \crosstabview
(hemen veya sonraki adımda) besleyebilirsiniz . Sevmek:
db=> SELECT section, status, ct FROM tbl \crosstabview
Yukarıdaki ile benzer sonuç, ancak yalnızca istemci tarafında bir temsil özelliğidir . Giriş satırları biraz farklı şekilde ele alınır, bu nedenle ORDER BY
gerekli değildir. İçin ayrıntılar \crosstabview
kılavuzu içinde. Sayfanın altında daha fazla kod örneği var.
Daniel Vérité (psql özelliğinin yazarı) tarafından dba.SE ile ilgili cevap:
Daha önce kabul edilen cevap eski.
Fonksiyonun varyantı crosstab(text, integer)
eski. İkinci integer
parametre yok sayılır. Mevcut kılavuzu alıntıladım :
crosstab(text sql, int N)
...
Eski sürümü crosstab(text)
. N
Değer sütunlarının sayısı her zaman çağıran sorgu tarafından belirlendiğinden, parametre artık yoksayılır
Gereksiz döküm ve yeniden adlandırma.
Bir satırın tüm öznitelikleri yoksa başarısız olur. Eksik öznitelikleri doğru şekilde işlemek için yukarıdaki iki giriş parametresine sahip güvenli değişkene bakın.
ORDER BY
öğesinin tek parametreli biçiminde gereklidir crosstab()
. Kullanım kılavuzu:
Uygulamada, SQL sorgusu her zaman ORDER BY 1,2
giriş satırlarının düzgün sıralandığından emin olmak için belirtmelidir