先贴我的算法,为查询oracle数据库的语句,其它语句也可,提供思路也可
<script language="php">
$sql = "select 日期,分公司,销售额 from 销售表 order by 日期";
$Stmt=@OCIParse($Conn,$sql);
@OCIexecute($Stmt);
$tp1="";//临时存放日期
$mid=0;//存放rowspan数
while (@OCIfetch($Stmt))
{
if(@OCIResult($Stmt,1)!=$tp1)//遇到不同日期,显示
{
if($tp1!="")
echo $beg.$mid.$end;
$beg="<tr><td align=center rowspan=";
$mid=1;
$end=">".@OCIResult($Stmt,1)."</td>";
$end.="<td>".@OCIResult($Stmt,2)."</td>";
$end.="<td>".@OCIResult($Stmt,3)."</td>";
$end.="</tr>";
}
else
{
$end.="<tr><td>".@OCIResult($Stmt,2)."</td>";
$end.="<td>".@OCIResult($Stmt,3)."</td>";
$end.="</tr>";
$mid++;
}
$tp1=@OCIResult($Stmt,1);
}
if($mid!==0)
echo $beg.$mid.$end;
@OCIFreecursor($Stmt);
</script>
<script language="php">
$sql = "select 日期,分公司,销售额 from 销售表 order by 日期";
$Stmt=@OCIParse($Conn,$sql);
@OCIexecute($Stmt);
$tp1="";//临时存放日期
$mid=0;//存放rowspan数
while (@OCIfetch($Stmt))
{
if(@OCIResult($Stmt,1)!=$tp1)//遇到不同日期,显示
{
if($tp1!="")
echo $beg.$mid.$end;
$beg="<tr><td align=center rowspan=";
$mid=1;
$end=">".@OCIResult($Stmt,1)."</td>";
$end.="<td>".@OCIResult($Stmt,2)."</td>";
$end.="<td>".@OCIResult($Stmt,3)."</td>";
$end.="</tr>";
}
else
{
$end.="<tr><td>".@OCIResult($Stmt,2)."</td>";
$end.="<td>".@OCIResult($Stmt,3)."</td>";
$end.="</tr>";
$mid++;
}
$tp1=@OCIResult($Stmt,1);
}
if($mid!==0)
echo $beg.$mid.$end;
@OCIFreecursor($Stmt);
</script>
--------------------------------------------------------------------
Id sub sales date
1 公司A 100 2006-1-1
2 公司B 200 2006-1-1
3 公司A 300 2006-1-2
4 公司B 400 2006-1-2
5 公司C 500 2006-1-2
6 公司A 300 2006-1-3
7 公司B 450 2006-1-3
8 公司C 300 2006-1-3
9 公司D 200 2006-1-3
---------------------------------------------------------------------
算法:
---------------------------------------------------------------------
$sql = "SELECT s.sub,s.sales,t.`date`,t.rowspan FROM sales s
INNER JOIN (SELECT count(*) as rowspan,`date` FROM sales GROUP BY `date`) t ON (s.`date` = t.`date`)
ORDER BY `date` DESC";
$result = mysql_query($sql);
$nums = mysql_num_rows($result);
$rowspan = 0 //rowspan初始值;
print("<table border='1'>\n");
for($i=0;$i<$nums;$i++)
{
$rows = mysql_fetch_array($result);
//判断是否为同一个 rowspan 值
if($rows['rowspan']<>$rowspan)
{
$rowspan = $rows['rowspan'];
print("<tr><td rowspan=".$rowspan.">".$rows['date']."</td>");
print("<td>".$rows['sub']."</td><td>".$rows['sales']."</td></tr>\n");
}
else
{
print("<tr><td>".$rows['sub']."</td><td>".$rows['sales']."</td></tr>\n");
}
}
print('</table>');
---------------------------------------------------------------------
<!--
window.onload=function()
{
var tab=document.getElementById("myTable");
for(i=tab.rows.length-1;i>0;i--)
{
for(j=tab.rows[i].cells.length-1;j>=0;j--)
{
if(tab.rows[i].cells[j].innerText==tab.rows[i-1].cells[j].innerText)
{
tab.rows[i-1].cells[j].rowSpan=tab.rows[i].cells[j].rowSpan+1;
tab.rows[i].deleteCell(j);
}
}
}
}
//-->
</script><table border="1" id="myTable">
<tr>
<td>日期</td>
<td>分公司</td>
<td>销售额</td>
</tr>
<tr>
<td>2006-1-1</td>
<td>公司A</td>
<td>100</td>
</tr>
<tr>
<td>2006-1-2</td>
<td>公司A</td>
<td>100</td>
</tr>
<tr>
<td>2006-1-1</td>
<td>公司C</td>
<td>200</td>
</tr>
<tr>
<td>2006-1-1</td>
<td>公司B</td>
<td>100</td>
</tr>
</table>
大家可以上以下地址看看我的页面http://108.bigwww.com/jsk2/q0261.htm
array (
'2006-1-1' => array (
array ('公司A', 100),
array ('公司B', 200),
),
'2006-1-2' => array (
array ('公司A', 300),
array ('公司B', 400),
array ('公司C', 500),
),
)
对于你的示例,就是
while (@OCIfetch($Stmt))
{
$ar[@OCIResult($Stmt,1)] = array(@OCIResult($Stmt,2), @OCIResult($Stmt,3));
}输出时
echo "<table border>";
foreach($ar as $k=>$v) {
$n = count($v);
foreach($v as $t) {
echo '<tr>';
if($n) {
echo "<td rowspan=$n>$k</td>";
$n = 0;
}
for($i=0; $i<count($t); $i++) { //合计在这个循环中进行
echo "<td>{$t[$i]}</td>";
}
echo "</tr>";
//在这里输出合计行
}
}
echo '</table>';显然这是一个通用的过程,与具体数据项的多少无关
如果这个比值很大,说明你需要考虑优化数据库查询,如果不大,那就没有必要了.像楼主这样的应用,最好的方式就是指定时间段获得结果,而不是固定每页有多少组结果,当然每页记录数也不错.每页行数限定也将就吧.再来就是对于查询语句的选择与优化了,oracle不太了解,应该同样也可以分析查询语句的,那么就把你知道的方法都分析下吧,看看哪个效率高些,至于页面的复杂表现形式,可以在程序中写.当然,如果你的访问量的压力高过数据库查询的压力,那么优化的方法可能稍有差别.另外,可以考虑冗余,如果你这些数据几乎没有修改操作,那么用冗余是很划算的.就像大家说静态页面好一样,呵呵.主要还是根据不同应用模式,均衡服务器的压力,使服务器压力不要出现突然的高峰导致系统挂掉.呵呵.
随便说说.