The table is a classic pivot table (or cross-tab). How this is constructed in SQL varies from vendor to vendor. Difficulty varies and sometimes can only be done with a temporary table.
Assuming you have a query that will generate the pivoted table: Updating the underlying data through a model displaying the pivot table through QSqlQueryModel is not possible. You will have to subclass QSqlQueryModel to provide the setData() method and the flags() method. There's an example in the reference documentation: Creating New Models
Another approach could be creating a derivative of QAbstractTableModel (or QSqlTableModel) and overriding the data(), setData() and flags() virtual methods. Internally the data() method could take the row and column, map them to a student and subject and perform a query to find the right value to return. On setData() the query generated is an UPDATE against the correct table(s).
Bookmarks