use strict; use warnings; use DBI; my $tmpFileName = 'temp'; open my $outFile, '>', $tmpFileName or die "Can't open $tmpFileName: $!\n"; print $outFile $_ for ; close $outFile; my $dbh = DBI->connect ("DBI:CSV:") or die "DBI connect failed: $DBI::errstr"; my $sth = $dbh->prepare ("SELECT * FROM temp"); my @structure; my %idMap; $sth->execute (); while (my $row = $sth->fetchrow_hashref) { my ($id, $name, $parent) = @{$row}{'id', 'name', 'parent'}; if (! $parent) { push @structure, {id => $id, name => $name, children => []}; $idMap{$id} = $structure[-1]; next; } if (exists $idMap{$parent}) { push @{$idMap{$parent}{children}}, {id => $id, name => $name, children => []}; $idMap{$id} = $idMap{$parent}{children}[-1]; next; } die "Can't handle children id provided before parent"; } $sth->finish (); $dbh->disconnect (); print dumpChildren($_) for @structure; sub dumpChildren { my ($node, $indent) = @_; $indent ||= ''; my $str = "$indent$node->{name}\n"; $indent .= ' '; $str .= dumpChildren ($_, $indent) for @{$node->{children}}; return $str; } __DATA__ id,name,parent 1,data1,0 2,data2,1 3,data3,1 4,data4,3 5,data5,4 #### data1 data2 data3 data4 data5