in reply to hoh or hoa data structure

Show us some code. Ideally a trivial database using something like the following as a starting point:

#!/usr/bin/perl use strict; use warnings; use DBI; unlink 'results'; open my $resFile, '>', 'results'; print $resFile <<DATA; Joe,A,1,85,90 Joe,A,1,80,99 Joe,A,2,50,70 Joe,A,2,60,65 Joe,A,2,87,89 Joe,B,1,82,92 Joe,B,3,30,51 Rob,A,1,85,90 Rob,A,1,80,99 Rob,A,2,50,70 Rob,A,2,60,65 Rob,A,2,87,89 Rob,B,1,82,92 Rob,B,3,30,51 DATA close $resFile; my $dbh = DBI->connect("DBI:CSV:") or die $DBI::errstr; my $sth = $dbh->prepare("SELECT * FROM results"); $sth->execute(); my $arrayRef = $sth->fetchall_arrayref; print +(join ', ', @$_), "\n" for @$arrayRef; exit;

Prints:

Joe, A, 1, 80, 99 Joe, A, 2, 50, 70 Joe, A, 2, 60, 65 Joe, A, 2, 87, 89 Joe, B, 1, 82, 92 Joe, B, 3, 30, 51 Rob, A, 1, 85, 90 Rob, A, 1, 80, 99 Rob, A, 2, 50, 70 Rob, A, 2, 60, 65 Rob, A, 2, 87, 89 Rob, B, 1, 82, 92 Rob, B, 3, 30, 51
True laziness is hard work

Replies are listed 'Best First'.
Re^2: hoh or hoa data structure
by rocky13 (Acolyte) on Jan 10, 2011 at 23:39 UTC

    I have updated the question with all of the code that I have. I am able to get the data results (5 columns) as shown but I cannot figure out a way to calculate the 4th and 5th column once ordered by the first three columns.

      Something like:

      #!/usr/bin/perl use strict; use warnings; use DBI; my $tableName = 'hist'; unlink $tableName; open my $resFile, '>', $tableName; print $resFile <<DATA; e_id,cus,ta,gd1,gd2 Joe,A,1,85,90 Joe,A,1,80,99 Joe,A,2,50,70 Joe,A,2,60,65 Joe,A,2,87,89 Joe,B,1,82,92 Joe,B,3,30,51 Rob,A,1,64,77 Rob,B,2,20,32 DATA close $resFile; my $dbh = DBI->connect("DBI:CSV:") or die $DBI::errstr; my $sth = $dbh->prepare("SELECT * FROM $tableName"); $sth->execute(); my $query = $dbh->selectall_arrayref( "select e_id, cus, ta, gd1, gd2 from $tableName order by e_id, cus +, ta", {Slice => {}}); my $gd1Total; my $gd2Total; my $currGroup; for my $row (@$query, {map {$_, 0} qw(e_id cus ta gd1 gd2)}) { my $group = join ',', @{$row}{qw(e_id cus ta)}; $currGroup = $group if !defined $currGroup; if ($group ne $currGroup) { print " Total $gd1Total, $gd2Total\n"; $gd1Total = $gd2Total = 0; $currGroup = $group; last if $group eq '0,0,0'; } print +(join ', ', @{$row}{qw(e_id cus ta gd1 gd2)}), "\n"; $gd1Total += $row->{gd1}; $gd2Total += $row->{gd2}; } exit;

      Prints:

      Joe, A, 1, 85, 90 Joe, A, 1, 80, 99 Total 165, 189 Joe, A, 2, 50, 70 Joe, A, 2, 60, 65 Joe, A, 2, 87, 89 Total 197, 224 Joe, B, 1, 82, 92 Total 82, 92 Joe, B, 3, 30, 51 Total 30, 51 Rob, A, 1, 64, 77 Total 64, 77 Rob, B, 2, 20, 32 Total 20, 32

      You'll have to fix the 'total' calculation to get the results you show however. My sample code simply sums the values.

      True laziness is hard work