Actuellement accepté réponse est obsolète.
- La variante de la fonction
crosstab(text, integer)
est dépassée. Le deuxième integer
paramètre est ignoré. Je cite l' actuel manuel:
tableau croisé(texte sql, int N) ...
Version obsolète de tableau croisé(texte). Le paramètre N est ignoré,
étant donné que le nombre de colonnes de valeur est toujours déterminée par l'appel de la requête
Inutile de casting, et de le renommer.
Il échoue si une ligne n'a pas tous les attributs. Il existe une variante en toute sécurité avec le texte de deux paramètres de traiter correctement avec des attributs manquants.
ORDER BY
est requis. Franchement, l'on a accepté la réponse est tout simplement faux. Je cite le manuel ici:
Dans la pratique, la requête SQL doit toujours spécifier l'ORDRE de 1,2 à assurer
que les lignes d'entrée sont bien ordonné
(Applicable uniquement pour le paramètre de forme de tableau croisé(), qui est utilisé.)
La bonne réponse
Installer le module additionnel tablefunc
qui assure la fonction crosstab()
une fois par base de données. Depuis PostgreSQL 9.1, vous pouvez utiliser CREATE EXTENSION
pour que:
CREATE EXTENSION tablefunc;
L'amélioration de cas de test
CREATE TEMP TABLE t (
section text
,status text
,ct integer -- don't use "count" as column name.
);
INSERT INTO t VALUES
('A', 'Active', 1), ('A', 'Inactive', 2)
,('B', 'Active', 4), ('B', 'Inactive', 5)
, ('C', 'Inactive', 7); -- no row for C with 'Active'
-
count
est un mot réservé, ne pas l'utiliser comme nom de colonne.
Forme Simple - pas d'ajustement pour les attributs manquants
crosstab()
avec un paramètre:
SELECT *
FROM crosstab(
'SELECT section, status, ct
FROM t
ORDER BY 1,2') -- needs to be "ORDER BY 1,2" here
AS ct ("Section" text, "Active" int, "Inactive" int);
Retourne:
Section | Actif | Inactif
---------+--------+----------
Un | 1 | 2
B | 4 | 5
C | 7|
- Pas besoin de casting, et de le renommer.
- Remarque les incorrecte résultat pour
C
: la valeur 7
est rempli pour la première colonne.
Forme sûre
crosstab()
avec deux paramètres:
SELECT * FROM crosstab(
'SELECT section, status, ct
FROM t
ORDER BY 1,2' -- could also just be "ORDER BY 1" here
,$$VALUES ('Active'::text), ('Inactive')$$)
AS ct ("Section" text, "Active" int, "Inactive" int);
Retourne:
Section | Actif | Inactif
---------+--------+----------
Un | 1 | 2
B | 4 | 5
C | | 7
Noter le bon résultat pour C
.
-
Le second paramètre peut être n'importe quelle requête qui ne renvoie qu'une seule ligne par attribut correspondant à l'ordre de la définition de la colonne à la fin. Souvent, vous voulez à la requête d'attributs distincts de la table sous-jacente comme ceci:
'SELECT DISTINCT attribute FROM tbl ORDER BY 1'
C'est dans le manuel.
Depuis que vous avez à énoncer toutes les colonnes dans une colonne d'une liste de définition de toute façon (sauf pour les pré-définies crosstab
variantes), il est régulièrement plus efficace de fournir une courte liste dans N
expression comme je viens de le démontrer:
()
Ou:
VALUES
C'est pas dans le manuel.
J'ai utilisé dollar citant à faire en citant plus facile.
Des exemples avancés
1 votes
J'avais une structure légèrement différente et j'ai trouvé cet exemple un peu difficile à comprendre. J'ai donc documenté ma manière de penser à ce sujet stackoverflow.com/q/49051959/808723 . Peut-être que c'est utile pour tout le monde.