my $dbh = ... # set up database sub display_groups { my ( $parent, $level ) = @_; # get all children of this parent my $sth = $dbh->prepare("SELECT id, gname FROM groups WHERE subgroup=? ORDER BY gname"); $sth->execute( $parent ); # display each child and its descendants while( my $row = $sth->fetchrow_hashref ) { print " " x $level; # indent print $row->{gname}, "\n"; display_groups( $row->{id}, $level + 1 ); } } # start with children of group 0 display_groups( 0, 0 );