# need '*table' and '*Tr' in order to use start_table() and start_Tr()
use CGI qw( :standard *table *Tr );
# ...
# note the map() calls each represent a nested for() loop
# and further that passing an array reference to td() creates a set of
blocks, one per element of the referenced array
print join( "\n", start_table,
start_Tr,
(map { map { td($_) } @$_ } @$db_results),
end_Tr,
end_table ), "\n";