我有一个MySQL表,其中包含我试图显示的事件列表(不是精确格式化):
2011
的一月 的
2012
的三月 的
我终于能够使用下面的PHP完成此任务,但我知道必须有更好的方法。正如您将看到的,有两个嵌套的for each
语句。 dateStart
列是DATE
。
$fetchEvents = $contentDB->query("SELECT id, title, description, dateStart, dateEnd, timeStart, timeEnd,
YEAR(dateStart) AS year, MONTH(dateStart) AS month, MONTHNAME(dateStart) AS monthName
FROM events_general ORDER BY dateStart");
while ($event = $fetchEvents->fetch())
{
$title = $event['title'];
$description = $event['description'];
$dateStart = $event['dateStart'];
$month = $event['monthName'];
$year = $event['year'];
$events[$year][$month][] = array(
'title' => $title,
'description' => $description,
'dateStart' => $dateStart);
}
foreach ($events as $year => $month)
{
echo "<p><strong>$year</strong>\n";
foreach ($month as $monthListing => $eventListing)
{
echo "
<p>$monthListing</p>\n
<div class=\"accordion\">\n
";
foreach ($eventListing as $event)
{
$title = $event['title'];
$description = $event['description'];
$dateStart = $event['dateStart'];
echo "
<h3><a href=\"#\">$title - $dateStart</a></h3>\n
<div>\n
$description \n
</div>\n
";
}
echo "</div>\n";
}
}
答案 0 :(得分:3)
这将在一次迭代中完成,但你需要摆弄手风琴的结束</div>
-
$fetchEvents = $contentDB->query("SELECT id, title, description, dateStart, dateEnd, timeStart, timeEnd,
YEAR(dateStart) AS year, MONTH(dateStart) AS month, MONTHNAME(dateStart) AS monthName
FROM events_general ORDER BY dateStart");
$prevYear = '';
$prevMonth = '';
while ($event = $fetchEvents->fetch())
{
$title = $event['title'];
$description = $event['description'];
$dateStart = $event['dateStart'];
$month = $event['monthName'];
$year = $event['year'];
if ($year <> $prevYear) {
// if a new year we definitely need to close the previous accordion div
// unless it's the first iteration
if ($prevMonth) {
echo '</div><!-- close accordion div -->';
}
echo "<p><strong>$year</strong>\n";
}
if ($year <> $prevYear || $month <> $prevMonth) {
// if new month but not new year close accordion
if ($year == $prevYear) {
echo '</div><!-- close accordion div -->';
}
echo "<p>$monthListing</p>\n";
echo "<div class=\"accordion\">\n";
}
echo "<h3><a href=\"#\">$title - $dateStart</a></h3>\n<div>\n$description \n</div>\n";
$prevYear = $year;
$prevMonth = $month;
}
// add final closing div here
echo '</div><!-- close accordion div -->';
答案 1 :(得分:0)
这是稍微修改过的查询。我有一个内部查询,只能抓住每年/每月的年,月和最后一个事件日期。然后,通过加入,我添加了IF()检查,如果日期开始匹配预先查询“MaxPerMthYr”的那个,则将标志设置为1,否则,将其保留为零。如果您在同一天有多个事件,这可能无法正常工作。如果是这种情况,则需要进行另一次修改,但IS可以保证正确输入。其余的PHP代码应该可以工作,但现在你将拥有你正在寻找的标志。
SELECT
id,
title,
description,
dateStart,
dateEnd,
timeStart,
timeEnd,
YEAR(dateStart) AS year,
MONTH(dateStart) AS month,
MONTHNAME(dateStart) AS monthName,
if( dateStart = MaxPerMthYr.LastDatePerGroup, 1, 0 ) as LastEntryPerGroup
FROM
events_general,
JOIN ( select YEAR(dateStart) AS perYear,
MONTH(dateStart) AS perMonth,
max( dateStart ) as LastDatePerGroup
from
events_general
group by
YEAR(dateStart) AS perYear,
MONTH(dateStart) AS perMonth ) MaxPerMthYr
ON Year( Events_General.dateStart ) = MaxPerMthYr.perYear
AND Month( Events_General.dateStart ) = MaxPerMthYr.perMonth
ORDER BY
dateStart