Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Sql:Mengubah baris menjadi kolom

Saya tidak dapat berbicara tentang MySQL, tetapi di PostgreSQL Anda dapat menggunakan fungsi tab silang dari fungsi meja modul:

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

Gabung kueri:

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

Hasil yang diinginkan:

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

Seperti yang Anda lihat, saya meletakkan daftar kolom secara eksplisit di PersonAttributePivot melihat. Saya tidak tahu cara pembuatan "pivot otomatis" dengan daftar kolom implisit.

EDIT:

Untuk besar daftar kolom (dengan asumsi selalu text type) sebagai solusinya, saya melihat sedikit pendekatan yang dimodifikasi:

Pembuatan tipe dinamis (di sini sederhana berbasis 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(");");

Hasil:

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

Pembungkus fungsi:

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

Pembuatan tampilan otomatis:

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

Hasil:

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. Menangani transaksi di lingkungan multithreaded

  2. PHP MySQL PDO:cara mempertahankan angka nol di depan kolom zerofill int

  3. Bagaimana saya bisa memilih bidang teks terpanjang saat menggunakan GROUP BY di mysql, a la MAX()?

  4. Bantuan dengan menggenggam (INNER?) GABUNG

  5. Memigrasikan Database MySQL dari Amazon RDS ke DigitalOcean