When a record is read from the database and converted to a Suneido object, empty fields are ignored – members are not created for them. This “works” because records have a default value for members of “”. This is why QueryAll (and other queries) work this way. (I have wondered if this was the best choice, but it is the way it has worked from the beginning.)
QueryView gets the fields for the query and then creates columns for all of them, regardless of whether there is data.
QueryView does not load all the data into memory, so it does not know if a given field is empty on all records.
I hope that explains it.