You're looping through each item in the $data array. The number of items in the $data array depends on the fetch mode you're using.
Since you're not explicitly specifying a fetch mode (fetch num, fetch both, fetch assoc, etc) you will have to assume the default fetch mode is being used.
The default fetch mode, assuming you're using fetch_array() method of a mysqli_result object, is both. This will represent each column of a mysqli_result row twice; once by column index and once by column name.
Since each column is represented twice, any and all row arrays (fetch_array) fetched will have an even number of items. x columns multiplied by 2 representations will always total an even number of representations (2, 4, 6, . So, expecting 3 is just not possible.
Now that we've covered your fetch both mode paradox, there are other inhibitions that I spot in your code.
Caliing $db->query($sql); should, if it doesn't, result with a return value that is not being stored. You should design the query() method of your sql class to return a value that represents the query's result!
$the_returned_result = $db->query($sql); // query the database and set the variable $the_returned_result to the returned value of sql::query()
$data = $the_returned_result->fetch_array(); // fetch from the returned value