Иерархически отсортированный вывод MySQL с PHP - PullRequest
1 голос
/ 22 марта 2012

Я пересматриваю навигацию моей системы новостей и хотел бы сделать это, используя минимальные запросы 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)

Я возился с этим весь день безуспешно.Я думаю, что лучше оставить это абсолютным экспертам.Рука, пожалуйста?

Ответы [ 3 ]

1 голос
/ 22 марта 2012

В настоящее время вы печатаете счетчик 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;
        } 
    }
}

Разница между выводом года и выводом месяца в том, что вы также хотите вывестичисло, связанное с месяцем, тогда как никакой дополнительной информации, связанной с годом, нет.Вы должны распечатать это, прежде чем перейти на следующий месяц.

1 голос
/ 22 марта 2012

Ваш

$month = $row['month'];

находится не в том месте.Он устанавливает переменную $ month для нового месяца, но подсчитывает число за предыдущие месяцы.

При первом запуске цикла while

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

никогда не может быть истинным, поэтому он входит в оператор else, отображающий месяц и число (которое равно 1, потому что вы установили его на 1 вверху) ...

0 голосов
/ 22 марта 2012

Я, вероятно, допустил здесь некоторую ошибку, но вы можете считать события за год-месяц и группировать их соответственно .. что-то вроде

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...