使用PHP对MySQL输出进行分层排序


Hierarchically sorted MySQL output with PHP

我正在修改我的新闻系统的导航,并希望使用最少的MySQL查询。我已经设法把它归结为一个查询,但似乎出了问题。如有任何帮助,我们将不胜感激。

我希望实现的是(从字面上)以下事件概述,按年度和月份分层排序,以及当月的事件数量:

2012
--04 (3)
--02 (1)
--01 (1)
2011 
--12 (3)
--11 (2)
--10 (3) 
--09 (1)
--07 (1)
--02 (1)

我很接近。我的查询如下:

SELECT start_date, date_format(start_date, "%Y") as year, date_format(start_date, "%m") as month FROM event ORDER BY start_date desc

然后,我的PHP循环如下:

    $year           = '';
    $year_counter   = 0;
    $month      = '';
    $month_counter  = 1;
    while($row = mysql_fetch_assoc($result)){
        if ( $year != $row['year'] ) {
            $year = $row['year'];
            $output .= $year.'<br />';
        }   
        if ( $month == $row['month'] ) {
            $month_counter++;
        } else {
            $month = $row['month'];
            $output .= '--'.$month.' ('.$month_counter.')<br />';
            $month_counter = 1;
        } 
    }

它完美地生成了所有内容,除了每月的事件数量,这些事件似乎总是一行之差(你可以看到与上面想要的结果的差异)。

2012
--04 (1)
--02 (3)
--01 (1)
2011
--12 (1)
--11 (3)
--10 (2)
--09 (3)
--07 (1)
--02 (1)

我整个下午都在修修补补,但没有成功。我认为最好把它留给绝对的专家。请帮忙?

当前,在为下个月更新month_counter之前,您正在打印它。在while循环之前,需要根据检索到的第一行而不是默认值初始化变量。

if ($row = mysql_fetch_assoc($result){
    $year = $row['year'];
    $month = $row['month'];
    $month_counter = 1;  //1 because you've already counted the first article
    // print out the first year
    $output .= $year.'<br />';
    while($row = mysql_fetch_assoc($result){
        if ( $year != $row['year'] ) {
            $year = $row['year'];
            $output .= $year.'<br />';
        }   
        if ( $month == $row['month'] ) {
            // You've found one more article for this month, so increment the count
            $month_counter++;
        } else {
            // You've hit a new month, so print out the information you collected
            // about the previous month
            $output .= '--'.$month.' ('.$month_counter.')<br />';
            $month = $row['month'];
            $month_counter = 1;
        } 
    }
}

输出年份和输出月份之间的区别在于,您还希望输出与月份相关的计数,而没有与年份相关的其他信息。在换到下个月之前,你必须打印出来。

您的

$month = $row['month'];

在错误的地方。它为新的月份设置了$month变量,但它一直在计算之前几个月的数字。

第一次运行while循环

if ( $month == $row['month'] )

永远不可能为真,所以它进入else语句,显示月份和计数(因为在顶部将其设置为1,所以为1)。。。

我可能在这里犯了一些错误,但您可以每月统计事件并对其进行相应的分组。。类似的东西

SELECT start_date, date_format(start_date, "%Y") as year, date_format(start_date, "%m") as month, date_format(start_date, "%Y%m") gr, COUNT(id) 
FROM event 
ORDER BY start_date desc 
GROUP BY gr