Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Sql:Transpozycja wierszy na kolumny

Nie mogę mówić o MySQL, ale w PostgreSQL możesz użyć funkcji crosstab z funkcja stołu moduł:

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

Dołącz do zapytania:

SELECT id, name, age, haircolor
FROM Person JOIN PersonAttributePivot USING(id)
ORDER BY id;

Poszukiwany wynik:

 id |    name    | age | haircolor 
----+------------+-----+-----------
  1 | Joe Bloggs | 27  | 
  2 | Jane Doe   |     | Brown
(2 rows)

Jak widzisz, umieściłem wyraźną listę kolumn w PersonAttributePivot pogląd. Nie znam żadnego sposobu tworzenia „automatycznego obrotu” z niejawną listą kolumn.

EDYTUJ:

Dla wielkiego lista kolumn (zakładając, że zawsze text type) jako obejście widzę takie mało zmodyfikowane podejście:

Tworzenie typów dynamicznych (tutaj trywialnie oparte na Javie):

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(");");

Wynik:

CREATE TYPE PersonAttributePivotType AS (
    PersonId integer,
    Age text,
    HairColor text
);

Opakowanie funkcji:

CREATE OR REPLACE FUNCTION crosstabPersonAttribute(text, text)
    RETURNS setof PersonAttributePivotType
    AS '$libdir/tablefunc','crosstab_hash' LANGUAGE C STABLE STRICT;

Automatyczne tworzenie widoku:

CREATE OR REPLACE VIEW PersonAttributePivot AS
    SELECT * FROM crosstabPersonAttribute
    (
       'SELECT PersonId, Key, Value FROM PersonAttribute',
       'SELECT DISTINCT Key FROM PersonAttribute ORDER BY Key'
    );

Wynik:

TABLE PersonAttributePivot;
 personid | age | haircolor
----------+-----+-----------
        1 | 27  |
        2 |     | Brown
(2 rows)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Aktualizacja serializowanej tablicy w mysql (bez odserializowania?)

  2. PHP wyświetla obraz BLOB z MySQL

  3. Rails 3 - nagle oczekujący błąd migracji

  4. MySQL - wybierz interwał co 2 godziny z kolumny timestamp

  5. Ostrzeżenie#1264:błąd poza zakresem w mysql