Je ne peux pas parler de MySQL, mais dans PostgreSQL, vous pouvez utiliser la fonction de tableau croisé de fonction de table modules :
CREATE OR REPLACE VIEW PersonAttributePivot AS
SELECT PersonId AS ID, Age, HairColor
FROM crosstab
(
'SELECT PersonId, Key, Value FROM PersonAttribute',
'SELECT DISTINCT Key FROM PersonAttribute ORDER BY Key'
)
AS
(
PersonId integer,
Age text,
HairColor text
);
Joindre la requête :
SELECT id, name, age, haircolor
FROM Person JOIN PersonAttributePivot USING(id)
ORDER BY id;
Résultat recherché :
id | name | age | haircolor
----+------------+-----+-----------
1 | Joe Bloggs | 27 |
2 | Jane Doe | | Brown
(2 rows)
Comme vous le voyez, j'ai mis une liste explicite de colonnes dans PersonAttributePivot
voir. Je ne connais aucun moyen de création de "pivot automatique" avec une liste de colonnes implicite.
MODIF :
Pour énorme liste de colonnes (en supposant toujours text
type) comme solution de contournement, je vois une approche si peu modifiée :
Création de type dynamique (ici trivialement basée sur Java) :
Class.forName("org.postgresql.Driver");
Connection c =
DriverManager.getConnection("jdbc:postgresql://localhost/postgres", "postgres", "12345");
Statement s = c.createStatement();
ResultSet rs = s.executeQuery("SELECT DISTINCT Key FROM PersonAttribute ORDER BY Key");
List<String> columns = new ArrayList<String>();
while (rs.next())
columns.add(rs.getString(1));
System.out.println("CREATE TYPE PersonAttributePivotType AS (");
System.out.println("\tPersonId integer,");
for (int i = 0; i < columns.size(); ++i)
{
System.out.print("\t" + columns.get(i) + " text");
if (i != columns.size() - 1)
System.out.print(",");
System.out.println();
}
System.out.println(");");
Résultat :
CREATE TYPE PersonAttributePivotType AS (
PersonId integer,
Age text,
HairColor text
);
Enveloppe de fonction :
CREATE OR REPLACE FUNCTION crosstabPersonAttribute(text, text)
RETURNS setof PersonAttributePivotType
AS '$libdir/tablefunc','crosstab_hash' LANGUAGE C STABLE STRICT;
Création de vue automatique :
CREATE OR REPLACE VIEW PersonAttributePivot AS
SELECT * FROM crosstabPersonAttribute
(
'SELECT PersonId, Key, Value FROM PersonAttribute',
'SELECT DISTINCT Key FROM PersonAttribute ORDER BY Key'
);
Résultat :
TABLE PersonAttributePivot;
personid | age | haircolor
----------+-----+-----------
1 | 27 |
2 | | Brown
(2 rows)