【问题标题】:Hierarchically sorted MySQL output with PHP使用 PHP 对 MySQL 输出进行分层排序
【发布时间】:2012-04-07 06:04:51
【问题描述】:

我正在修改我的新闻系统的导航,并希望使用最少的 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)

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

【问题讨论】:

  • 如果将月份循环放在年份 if 表达式中会发生什么?
  • 如果我这样做,只会显示每年的第一个月...

标签: php mysql sorting loops


【解决方案1】:

你的

$month = $row['month'];

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

第一次运行while循环

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

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

【讨论】:

  • 你应该在第一个 if 语句中设置 $month-variable ;)
  • 谢谢,但是如果我在第一个 if 语句(年份语句)中设置了月份变量,那么 2012 年的第一个月(4)就不见了。能否请您提供更多见解?
【解决方案2】:

我可能在这里犯了一些错误,但是您可以计算每年每月的事件并相应地对它们进行分组......类似

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

【讨论】:

    【解决方案3】:

    目前,您在为下个月更新之前打印 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;
            } 
        }
    }
    

    输出年份和输出月份的区别在于,您还想输出与月份关联的计数,而没有与年份关联的其他信息。您必须在更改到下个月之前打印它。

    【讨论】:

    • 谢谢,但这会产生意想不到的结果...缺少2012年的第一个月(即04)...
    • 对不起,我忘了说你还需要在 else 块中用 $month= 切换 $output。
    • 嗨,我不知道我是否理解正确,因为把它放在 else 块中会导致脚本只显示年份。变量输出应包含所有内容,并在脚本末尾返回...
    • 我认为我对您的评论的回复不清楚。我根据我的评论编辑了上面的答案。我希望这会有所帮助。
    • 非常非常好!这行得通,但仍然有一点障碍。 2012 年 1 月的事件显示为 2011 年的第一个月。此外,最后一个事件,即 2011 年 2 月被剥离......知道吗?谢谢!
    猜你喜欢
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多