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

Styl spłaszczenia tabeli przestawnej dla widoku Datagrid

W zależności od tego, co robisz, w niektórych przypadkach możesz utworzyć zapytanie lub przygotowaną instrukcję, aby zrobić to za Ciebie. Są to zwykle podsumowanie ustalonego zestawu znanych kolumn. W tym przypadku nie wiemy, ile będzie kolumn dat ani jakie one są. Możemy to zrobić w kodzie.

Użyłem Access zamiast mySQL, ale koncepcja jest taka sama. Uczyniłem to również bardziej skomplikowanym, rejestrując frekwencję według klas, które nie spotykają się codziennie. Dane początkowe:

Nie będę używał nazwy klasy w wynikach, powoduje to, że ekran jest zbyt szeroki.

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

Nie jest tak skomplikowany, jak mogłoby się wydawać.

  1. Pobierz główny zbiór danych do pracy
  2. Uzyskaj listę unikalnych imion uczniów
  3. Nazwy kolumn do użycia pochodzą z zapytania linq w celu wyodrębnienia unikalnych dat klas w tabeli danych
  4. Utwórz nową DataTable dla wyników.
    • Po StudentName i ClassCode pętla dodaje jedną kolumnę na każdą datę dowolną klasa spełnia. Nazwy kolumn/tekst nagłówka pochodzą z ColNames lista/tablica właśnie utworzona.

Po utworzeniu docelowej tabeli DataTable możesz rozpocząć kopiowanie do niej danych. Ponownie, zamiast OleDB... obiekty, których użyłbyś MySQL... obiekt, ale działają tak samo.

  1. Przejdź przez wszystkich uczniów z listy uczniów
  2. Dla każdego z nich wyodrębnij listę wszystkich zajęć, w których uczestniczyli, z zestawu danych podstawowych
  3. Przejdź przez te klasy
  4. Wyodrębnij wiersze dla bieżącej klasy ze zbioru danych o klasie ucznia
  5. Utwórz nowy DataRow używając zmiennych iteracyjnych Student i Class dla pierwszych 2 kolumn.
  6. Konwertuj każdą wartość DateTime w bieżącym zestawie danych klasy Student na ten sam format, który został użyty do utworzenia kolumn wyników (cname ).
    • użyj go, aby skopiować ich status:newRow.Item(cname) = statRow.Item("Status") do nowego wiersza
    • Ponieważ zajęcia nie spotykają się codziennie, niektóre komórki będą puste (DbNull )
  7. Dodaj nowy wiersz do końcowej tabeli danych

Byłoby prościej bez raportowania Według klasy i po prostu zgłaszaj stan dla całego dnia. Wynik:

Najbardziej zagmatwaną częścią jest użycie danych daty w jednej tabeli danych jako kolumna nazwa w innym i usuwając część czasu.

To tylko pierwszy krok, więc prawdopodobnie można go dopracować. Część przetwarzania może być wykonana w SQL; DateTime.Parse metoda konwersji DateTime dane do ciągu w tym samym formacie (usuń czas itp.) mogą być własną procedurą. Użyłbym również dwuznakowego formatu roku, aby nagłówki były nieco węższe.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak wyświetlić kategorie, podkategorie, podkategorie na liście wyboru - php/mysql?

  2. Niezdefiniowany indeks:REMOTE_ADDR podczas migracji Laravel

  3. Rozłączenie bazy danych mysql węzła JS

  4. jak dodać super uprawnienia do bazy mysql?

  5. Mysql Konwertuj kolumnę na wiersz (tabela przestawna)