In what circumstances would a block appear in the Leveldb .ldb index but have no data in a .dat file?
Bitcoin Core may only have just the block headers for some blocks, not the full block data. Such block headers would get an entry into the chainstate and block index as a block that the node knows about. However the node does not have the full block data corresponding to that header so there is no corresponding block data in the blk*.dat files.

This situation happens during syncing (since Bitcoin Core will fetch block headers first and then the blocks), when there are orphan blocks, and when there are chain forks.