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

Ratakan gaya Pivot Tabel untuk Datagridview

Bergantung pada apa yang Anda lakukan, dalam beberapa kasus Anda bisa membuat kueri atau pernyataan yang disiapkan untuk melakukan ini untuk Anda. Ini biasanya untuk meringkas satu set tetap kolom yang diketahui. Dalam hal ini kita tidak tahu berapa banyak kolom tanggal yang akan ada atau apa itu. Jadi, kita bisa melakukannya dalam kode.

Saya menggunakan Access alih-alih mySQL, tetapi konsepnya sama. Saya juga membuatnya lebih rumit dengan mencatat kehadiran berdasarkan kelas yang tidak bertemu setiap hari. Data awal:

Saya tidak akan menggunakan nama kelas dalam hasil, itu membuat tampilan terlalu lebar.

Dim sql = <sql>  
           ((Use your own SQL obviously))
           </sql>.Value

Dim dtTemp As New DataTable

' get the data
Using dbcon As OleDbConnection = GetACEConnection(),
    cmd As New OleDbCommand(sql, dbcon)

    dbcon.Open()
    Using da As New OleDbDataAdapter(cmd)
        da.Fill(dtTemp)
    End Using

End Using

' unique list of "date" columns in the result set
' ORDERBY Date is in the SQL
Dim colNames = dtTemp.AsEnumerable().
                Select(Function(s) DateTime.Parse(s.Item("Date").ToString).
                        ToString("MM/dd/yyyy")).
                Distinct.ToList()

' unique list of students
Dim Students = dtTemp.AsEnumerable().Select(Function(q) q.Item("Name")).
                Distinct.ToList()

' the final table to use with the DGV
Dim dt As New DataTable
Dim colName As String

' add the name and class code designation columns
dt.Columns.Add(New DataColumn(dtTemp.Columns(0).ColumnName, GetType(String)))
dt.Columns.Add(New DataColumn(dtTemp.Columns(1).ColumnName, GetType(String)))

' add a "MM/dd/yyyy" text column for each possible class day
For n As Int32 = 0 To colNames.ToArray.Count - 1
    colName = DateTime.Parse(colNames(n).ToString).ToString("MM/dd/yyyy")
    dt.Columns.Add(New DataColumn(colName, GetType(String)))
Next

Dim newRow As DataRow

' loop thru all students
For Each s In Students
    ' the student-class dataset
    Dim drs As DataRow() = dtTemp.Select(String.Format("Name = '{0}'", s.ToString)).
                            OrderBy(Function(o) o.Item("ClassCode")).ToArray

    ' create list of classes for this student
    Dim classes = drs.AsEnumerable.
            Select(Function(q) q.Item(1).ToString).Distinct.ToArray

    For Each classcode As String In classes
        ' filter the drs results to the current class
        Dim datestat As DataRow() = drs.AsEnumerable.
                Where(Function(q) q.Item(1).ToString = classcode).ToArray

        ' create new row, copy the data from drs.Rows to dt.columns
        newRow = dt.NewRow
        newRow.Item(0) = s
        newRow.Item(1) = classcode
        ' NOTE since not all students will have a class everyday, some
        ' "status" cells will be dbNull!
        For Each statRow In datestat
            Dim cname As String = DateTime.Parse(statRow.Item("Date").
                                                     ToString()).ToString("MM/dd/yyyy")
            newRow.Item(cname) = statRow.Item("Status")
        Next
        dt.Rows.Add(newRow)
    Next

Next

dgv.AutoGenerateColumns = True
dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader)
dgv.DataSource = dt

Ini tidak serumit kelihatannya.

  1. Dapatkan kumpulan data master untuk bekerja
  2. Dapatkan daftar nama siswa yang unik
  3. Nama kolom yang akan digunakan berasal dari kueri linq untuk mengekstrak tanggal kelas unik dalam tabel data
  4. Buat DataTable baru untuk hasilnya.
    • Setelah StudentName dan ClassCode loop menambahkan satu kolom untuk setiap tanggal yang apa saja kelas bertemu. Nama kolom/teks header berasal dari ColNames daftar/array baru saja dibuat.

Dengan DataTable tujuan dibuat, Anda dapat mulai menyalin data ke sana. Sekali lagi, alih-alih OleDB... objek yang akan Anda gunakan MySQL... objek, tetapi fungsinya sama.

  1. Mengulang semua siswa dalam daftar siswa
  2. Untuk masing-masing, ekstrak daftar semua kelas yang mereka hadiri dari kumpulan data master
  3. Mengulang kelas-kelas tersebut
  4. Ekstrak baris untuk kelas saat ini dari kumpulan data Kelas-Siswa
  5. Buat DataRow baru menggunakan vars iterasi Siswa dan Kelas untuk 2 kolom pertama.
  6. Konversi setiap nilai DateTime dalam kumpulan data Kelas-Siswa saat ini ke format yang sama yang digunakan untuk membuat kolom hasil (cname ).
    • gunakan untuk menyalin status mereka:newRow.Item(cname) = statRow.Item("Status") ke baris baru
    • Karena kelas tidak bertemu setiap hari, beberapa sel akan kosong (DbNull )
  7. Tambahkan baris baru ke tabel data akhir

Akan lebih mudah tanpa pelaporan Berdasarkan Kelas, dan cukup laporkan statusnya sepanjang hari. Hasilnya:

Bagian yang paling membingungkan adalah menggunakan Tanggal data dalam satu datatable sebagai kolom nama di tempat lain dan menghapus bagian waktu.

Itu hanya umpan pertama, jadi kemungkinan bisa disempurnakan. Beberapa pemrosesan mungkin dapat dilakukan dalam SQL; DateTime.Parse metode untuk mengonversi DateTime data ke string dalam format yang sama (menghapus Waktu dll) bisa menjadi prosedurnya sendiri. Saya juga akan menggunakan format tahun 2 karakter untuk membuat header sedikit lebih sempit.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql memasukkan tanggal kosong jika tanggalnya tidak benar

  2. Cara mengimpor file excel ke database MySQL

  3. Bagaimana cara mengimpor dump mysql sambil mengganti nama beberapa tabel/kolom dan tidak mengimpor yang lain sama sekali?

  4. Kunci asing dalam masalah migrasi Laravel 4

  5. bagaimana cara mengembalikan database di mysql?