db->tableExists('reimbursement_batches') || $this->db->fieldExists('yearly_batch_number', 'reimbursement_batches')) { return; } $fields = [ 'yearly_batch_number' => [ 'type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'default' => 0, 'null' => false, 'after' => 'title', ], ]; $this->forge->addColumn('reimbursement_batches', $fields); $this->fillExistingBatchNumbers(); } public function down() { if (! $this->db->tableExists('reimbursement_batches') || ! $this->db->fieldExists('yearly_batch_number', 'reimbursement_batches')) { return; } $this->forge->dropColumn('reimbursement_batches', 'yearly_batch_number'); } private function fillExistingBatchNumbers(): void { $this->db->query("SET @prev_school_year := '', @row_number := 0"); $this->db->query( 'UPDATE reimbursement_batches b JOIN ( SELECT id, (@row_number := IF(@prev_school_year = COALESCE(school_year, \'\'), @row_number + 1, 1)) AS seq, @prev_school_year := COALESCE(school_year, \'\') AS school_year_marker FROM reimbursement_batches ORDER BY COALESCE(school_year, \'\'), COALESCE(opened_at, \'1970-01-01 00:00:00\'), id ) ranks ON b.id = ranks.id SET b.yearly_batch_number = ranks.seq' ); } }