Vale, la idea es que la segunda columna de la tabla debe reducir los casos iguales, por medio de un 'rowspan'.
La solución no es obvia (o es que yo me he liado al buscarla, seguro).
Lo primero que haría sería cambiar el bucle while() con el fetchrow_hashref(), por una sola llamada fetchall_arrayref() (o si es posible, selectall_arrayref()). Eso lo que hace es devolver toda la tabla de resultados, en forma de una referencia a un
array, en que cada elemento es una referencia a una fila de los resultados.
Teniendo esa estructura bidimensional, podemos recorrerla verticalmente, para ver por dónde tenemos que recortar.
Llegados a una fila, en que tengamos algo en la columna 'descrip_comp', iniciamos una búsqueda hacia abajo, hasta ver dónde llega el 'rowspan'. En las filas intermedias, que coincidan con la primera, vamos "borrando" las celdas, para que así sepamos en las siguientes vueltas, que esas celdas no deben representarse.
He hecho un programa de prueba:
Using perl Syntax Highlighting
#!/usr/bin/perl
use v5.10;
use CGI qw':standard *table';
my $fetchall_arrayref = [
{
'descrip_comp' => "Feature 1",
'fecha_sale' => "20130723",
'medidas' => "1.50x2.10x1.78",
'causa' => "venta",
'id_causa' => "id1",
},
{
'descrip_comp' => "Feature 1",
'fecha_sale' => "20130723",
'medidas' => "1.50x2.10x1.78",
'causa' => "venta",
'id_causa' => "id2",
},
{
'descrip_comp' => "Feature 1",
'fecha_sale' => "20130723",
'medidas' => "1.50x2.10x1.78",
'causa' => "venta",
'id_causa' => "id3",
},
{
'descrip_comp' => "Feature 2",
'fecha_sale' => "20130723",
'medidas' => "1.50x2.10x1.78",
'causa' => "venta",
'id_causa' => "id4",
},
{
'descrip_comp' => "Feature 3",
'fecha_sale' => "20130723",
'medidas' => "1.50x2.10x1.78",
'causa' => "venta",
'id_causa' => "id5",
},
{
'descrip_comp' => "Feature 3",
'fecha_sale' => "20130723",
'medidas' => "1.50x2.10x1.78",
'causa' => "venta",
'id_causa' => "id6",
},
];
my $anterior_descrip = '';
my $indice_primer_descrip;
say start_html;
say start_table({-border => 3});
for my $i (0 .. $#$fetchall_arrayref) {
my $rowspan = 1;
my $reg = $fetchall_arrayref->[$i];
my $descrip_comp = $reg->{'descrip_comp'};
my $fecha_sale = $reg->{'fecha_sale'};
my $medidas = $reg->{'medidas'};
my $causa = $reg->{'causa'};
my $id_causa = $reg->{'id_causa'};
if ($descrip_comp) { # buscar campo diferente en el resto de líneas
my $j;
for($j = $i+1; $j <= $#$fetchall_arrayref; $j++) { # recorremos desde la siguiente línea, hasta el final
last if $fetchall_arrayref->[$j]->{'descrip_comp'} ne $descrip_comp; # salimos si hemos encontrado una celda distinta
$fetchall_arrayref->[$j]->{'descrip_comp'} = ''; # la celda es igual, así que la limpiamos
}
$rowspan = $j - $i; # tamaño del rowspan
}
my $celda_descrip;
if ($rowspan == 1) { # puede que sea celda normal, o abreviada
if ($descrip_comp) {
$celda_descrip = td($descrip_comp); # celda normal
}
else {
$celda_descrip = ''; # abreviada: no hay celda
}
}
else {
$celda_descrip = td({-rowspan => $rowspan}, $descrip_comp); # demás casos: rowspan
}
### creación de la línea de tabla
say Tr(td($i), $celda_descrip, td([ $fecha_sale, $medidas, $causa, $id_causa ]));
}
say end_table;
say end_html;
__END__
Coloreado en 0.004 segundos, usando
GeSHi 1.0.8.4
y da como resultado:
Using html4strict Syntax Highlighting
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
<table border="3">
<tr><td>0</td> <td rowspan="3">Feature 1</td> <td>20130723</td> <td>1.50x2.10x1.78</td> <td>venta</td> <td>id1</td></tr>
<tr><td>1</td> <td>20130723</td> <td>1.50x2.10x1.78</td> <td>venta</td> <td>id2</td></tr>
<tr><td>2</td> <td>20130723</td> <td>1.50x2.10x1.78</td> <td>venta</td> <td>id3</td></tr>
<tr><td>3</td> <td>Feature 2</td> <td>20130723</td> <td>1.50x2.10x1.78</td> <td>venta</td> <td>id4</td></tr>
<tr><td>4</td> <td rowspan="2">Feature 3</td> <td>20130723</td> <td>1.50x2.10x1.78</td> <td>venta</td> <td>id5</td></tr>
<tr><td>5</td> <td>20130723</td> <td>1.50x2.10x1.78</td> <td>venta</td> <td>id6</td></tr>
</table>
</body>
</html>
Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
Y sale una bonita tabla, con los rowspan correctos.