Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm phẳng kiểu Pivot của bảng cho Datagridview

Tùy thuộc vào những gì bạn đang làm, trong một số trường hợp, bạn có thể tạo một truy vấn hoặc câu lệnh chuẩn bị để thực hiện việc này cho bạn. Đây thường là để tóm tắt một tập hợp cố định của các cột đã biết. Trong trường hợp này, chúng tôi không biết sẽ có bao nhiêu cột ngày tháng hoặc chúng là gì. Vì vậy, chúng tôi có thể làm điều đó trong mã.

Tôi đã sử dụng Access thay vì mySQL, nhưng khái niệm vẫn giống nhau. Tôi cũng làm cho nó phức tạp hơn bằng cách ghi nhật ký điểm danh theo lớp không gặp hàng ngày. Dữ liệu bắt đầu:

Tôi sẽ không sử dụng tên lớp trong kết quả, nó làm cho màn hình hiển thị quá rộng.

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

Nó không phức tạp như vẻ ngoài của nó.

  1. Nhận tập dữ liệu chính để làm việc
  2. Nhận danh sách các tên sinh viên duy nhất
  3. Các tên cột để sử dụng đến từ một truy vấn linq để trích xuất các ngày lớp duy nhất trong bảng dữ liệu
  4. Tạo một DataTable mới để biết kết quả.
    • Sau StudentNameClassCode vòng lặp thêm một cột cho mỗi ngày bất kỳ họp lớp. Tên cột / văn bản tiêu đề đến từ ColNames danh sách / mảng vừa tạo.

Với DataTable đích được tạo, bạn có thể bắt đầu sao chép dữ liệu vào đó. Một lần nữa, thay vì OleDB... các đối tượng bạn sẽ sử dụng MySQL... nhưng chúng hoạt động giống nhau.

  1. Lặp qua tất cả các sinh viên trong danh sách sinh viên
  2. Đối với mỗi lớp, trích xuất danh sách tất cả các lớp học mà họ đã tham dự từ tập dữ liệu chính
  3. Vòng lặp qua các lớp đó
  4. Trích xuất các hàng cho lớp hiện tại từ tập dữ liệu Lớp sinh viên
  5. Tạo một DataRow mới bằng cách sử dụng các vars lặp lại Sinh viên và Lớp học cho 2 cột đầu tiên.
  6. Chuyển đổi từng giá trị DateTime trong tập dữ liệu Lớp sinh viên hiện tại sang cùng một định dạng được sử dụng để tạo các cột kết quả (cname ).
    • sử dụng nó để sao chép trạng thái của họ:newRow.Item(cname) = statRow.Item("Status") sang hàng mới
    • Vì các lớp không gặp nhau hàng ngày, một số ô sẽ trống (DbNull )
  7. Thêm hàng mới vào dữ liệu cuối cùng

Sẽ đơn giản hơn nếu không có báo cáo Theo Lớp và chỉ cần báo cáo trạng thái cho cả ngày. Kết quả:

Phần khó hiểu nhất là sử dụng dữ liệu Ngày trong một cơ sở dữ liệu dưới dạng cột tên khác và loại bỏ phần thời gian.

Đó chỉ là một lần vượt qua đầu tiên, vì vậy nó có thể được tinh chỉnh. Một số xử lý có thể được thực hiện trong SQL; DateTime.Parse phương pháp chuyển đổi DateTime dữ liệu thành một chuỗi có cùng định dạng (loại bỏ Thời gian, v.v.) có thể là thủ tục riêng của nó. Tôi cũng sẽ sử dụng định dạng năm 2 ký tự để làm cho tiêu đề hẹp hơn một chút.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Không tìm thấy bảng cơ sở di chuyển Laravel 4

  2. 3 Điểm hàng đầu - MySQL

  3. thụt lề không nhất quán với Python sau khi tách

  4. Làm cách nào để sử dụng cùng (các) kết nối MySQL cho toàn bộ ứng dụng Node.js của tôi?

  5. Lấy Id được chèn lần cuối từ MySQL trong Yii