SELECT category_id, category_name, main_category FROM test ORDER BY main_category, category_id #### $category{$category_id} = [ $category_name, [] ]; #### push @{$category{$main_category}->[1]}, $category_id; #### %category = ( 1 => [ 'One', [5, 6, 7] ], 2 => [ 'Two', [8, 9] ], 3 => [ 'Three', [] ], 4 => [ 'Four', [] ], 5 => [ 'Six', [10, 13] ], 6 => [ 'Seven', [] ], 7 => [ 'Eight', [] ], ... ); #### sub print_categories { my $level = shift; foreach my $id (@_) { print "$level: $category{$id}->[0]\n"; print_categories($level + 1, @{$category{$id}->[0]}); } } print_categories(0, @top_level_categories);