in reply to Hash of Hashes

The first thing is to change your query:

select course_id,course_name,course_sitting_id,course_sitting_date from courses order by course_id, course_name, course_sitting_id

Then, you just need to realize that whenever the course_name changes, you want to begin a new entry in your results.

... my %courses; for my $row (@results) { my $course_id = $row->[0]; $courses{ $course_id } ||= { ... desc => $row->[1], sittings => {}, ... }; $courses{ $course_id }->{ sittings }->{ $row->[2] } = $row->[3]; };

Also see perldsc and Data::Dumper.