Как сгруппировать данные таблицы базы данных по дням и создать календарь с таблицей HTML? - PullRequest
0 голосов
/ 07 октября 2018

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

Вот несколько примеров строк:

enter image description here

Вот мой код для получения массива

$query="SELECT event_date_start, event_date_end, event_description, event_type, swim_club_assigned 
         FROM eventcalendar 
         WHERE event_date_start like '$search_date%'";
$result = mysqli_query($con, $query);

echo "<br>";

// Only loop if there is a result.
if ($result){
    $r = []; // You aren't exactly clear on 'myData'.  In this instance, I am setting the rows inside of it.
    while ($row = $result->fetch_object()) {
        $r[] = $row;
    }
    $result->close(); // Free result set
}

print_r ($ r);дает мне массив ниже

Array (
    [0] => stdClass Object (
        [event_date_start] => 2018-10-01
        [event_date_end] => 2018-10-01
        [event_description] => Preparation Meet (LC) - Template: A
        [event_type] => GCRSA Club Meet
        [swim_club_assigned] => Gold Coast North SC Inc
    )
    [1] => stdClass Object (
        [event_date_start] => 2018-10-11
        [event_date_end] => 2018-10-11
        [event_description] => Sprint Meet (LC) - Template: H
        [event_type] => GCRSA Club Meet
        [swim_club_assigned] => Bond SC Inc
    )
    [2] => stdClass Object (
        [event_date_start] => 2018-10-31
        [event_date_end] => 2018-10-31
        [event_description] => Reg Winter Championships (SC) - Template: XY
        [event_type] => GCRSA Championship
        [swim_club_assigned] => 
    )
) 

Я хочу иметь возможность извлечь из массива (где тип события = $something и дата начала = $a_date, а затем отобразить $swim_club и$event_description.

while($row = fetch_assoc($r)) {
    if (($row["event_type"] == 'GCRSA Championship') && ($row["event_date_start"] == $day)){
        echo  "{$row['swim_club_assigned']} {$row['event_description']}";
    }
}

Я пытался выяснить, как извлечь данные ключа из массива для каждой строки (может быть более одного события на дату начала в массиве), но яне могу понять синтаксис для извлечения строки из массива и затем извлечения значения из ключа.

Чтобы было понятно, это календарь, который я пытаюсь заполнить, и результаты должны бытьвставлен в ячейку в соответствующей строке даты. Поэтому я подумал, что лучше использовать один запрос вверху, а затем выполнять итерацию по массиву (как в примере выше) в каждой ячейке, совпадающей с датой события и днемсоответствующая ячейка. Календарь, который я использую, находится ниже (с комментариями, чтобы показать ячейку, в которую мне нужно вставить данные)

<table class="table table-bordered">
    <thead>
         <tr>
            <th rowspan="2" colspan="2">Date</th>
            <th colspan="3">GCRSA Region</th>
            <th colspan="2">State, SAL, Intl</th>
            <th colspan=2><center>Other events</center> </th>
         </tr>
         <tr style="border-bottom: 1pt Darkblue;">
            <th>Club meet</th>
            <th>Championship</th>
            <th>Development</th>
            <th>SQ</th>
            <th>Sal</th>
            <th>School Meets</th>
            <th>Qld School Holidays</th>
          </tr>
    </thead>
    <tbody>
        <?php
        // First day of the month.
        $date_start = date('Y-m-01', strtotime($query_date));
        $day = date('Y-m-01', strtotime($query_date));
        for($i= 1; $i < date('t', strtotime($query_date)) + 1; $i++){
        ?>
            <tr>
            <td <?php if (date('w',strtotime($day)) == 0 || date('w',strtotime($day)) == 6 ){
                echo "style='background-color:red;'";
            }?>><?php echo date('M d, Y',strtotime($day)); 

            ?></td>
            <td <?php if (date('w',strtotime($day)) == 0 || date('w',strtotime($day)) == 6 ){
                echo "style='background-color:red;'";
            }?>><?php echo date('l',strtotime($day)); ?></td>

            <td> <?php //this bit is not working. need to iterate through array result $r to filter appropriate events here 
            while($row = mysqli_fetch_assoc($r)) {
                if  (($row["event_type"] == 'GCRSA Club Meet') && ($row["event_date_start"] == $day)){
                    echo  "{$row['swim_club_assigned']} {$row['event_description']}";
                }
            }
            ?></td>

            <td> <?php //this bit is not working. need to iterate through array result $r to filter appropriate events here 
            while($row = mysqli_fetch_assoc($r)) {
                if  (($row["event_type"] == 'GCRSA Championship') && ($row["event_date_start"] == $day)){
                    echo  "{$row['swim_club_assigned']} {$row['event_description']}";
                }
            }
            ?></td>

        <?php
            for($j =1;$j<=5;$j++){
                echo "<td></td>".PHP_EOL;
            }
        ?>
        </tr>
        <?php 
        $day = date('Y-m-d', strtotime('+1 day', strtotime($day)));
        } 
        ?>                                    
    </tbody>

1 Ответ

0 голосов
/ 07 октября 2018

Сначала фрагмент / файл, затем объяснение и детали ...

<style>
.table-bordered {border: solid 1px grey;}
thead tr th {border: solid 1px blue;}
tbody tr td {border: solid 1px green;}
.Sday {background-color: red;}
</style>
<?php
if (!$conn = new mysqli("localhost", "root","","db")) {
    echo "Database Connection Error"; // $conn->connect_error
} else {
    // Generate derived table comprised of united hardcoded dates for the current month with minimal function calls
    $ym = date('Y-m-');
    $derived_table = '';
    for ($d = 1, $end = date('t'); $d <= $end; ++$d) {
        $date = $ym . str_pad($d, 2, 0, STR_PAD_LEFT);  // format the date without calling strtotime() & date() each iteration
        if ($d == 1) {
            $derived_table .= "SELECT '$date' AS event_date_start";  // only need to name the first column
        } else {
            $derived_table .= " UNION SELECT '$date'";
        }
    }
    $query = "SELECT 
                DATE_FORMAT(A.event_date_start, '%b %e, %Y') AS Date,
                DAYNAME(A.event_date_start) AS Day,
                GROUP_CONCAT(
                  IF(event_type = 'GCRSA Club Meet', CONCAT(swim_club_assigned, ' ', event_description), null)
                  SEPARATOR '<br>'
                ) AS `Club Meet`,
                GROUP_CONCAT(
                  IF(event_type = 'GCRSA Championship', CONCAT(swim_club_assigned, ' ', event_description), null)
                  SEPARATOR '<br>'
                ) AS `Championship`
              FROM ($derived_table) A
              LEFT JOIN eventcalendar B ON A.event_date_start = B.event_date_start
              GROUP BY A.event_date_start";
    if (!$result = $conn->query($query)) {
        echo "Syntax Error"; // $conn->error
    } else {
        ?>
        <table class="table table-bordered">
            <thead>
                 <tr>
                    <th rowspan="2" colspan="2">Date</th>
                    <th colspan="3">GCRSA Region</th>
                    <th colspan="2">State, SAL, Intl</th>
                    <th colspan="2">Other events</th>
                 </tr>
                 <tr style="border-bottom: 1pt Darkblue;">
                    <th>Club meet</th>
                    <th>Championship</th>
                    <th>Development</th>
                    <th>SQ</th>
                    <th>Sal</th>
                    <th>School Meets</th>
                    <th>Qld School Holidays</th>
                  </tr>
            </thead>
            <tbody>     
                <?php
                while ($row = $result->fetch_assoc()) {
                    echo "<tr>";
                        echo "<td class=\"{$row['Day'][0]}day\">{$row['Date']}</td>";
                        echo "<td class=\"{$row['Day'][0]}day\">{$row['Day']}</td>";
                        echo "<td>{$row['Club Meet']}</td>";
                        echo "<td>{$row['Championship']}</td>";
                        echo "<td></td>";
                        echo "<td></td>";
                        echo "<td></td>";
                        echo "<td></td>";
                        echo "<td></td>";
                    echo "</tr>";
                }
                ?>
            </tbody>
        </table>
        <?php
    }
}

SQL-запрос является рабочей лошадкой этого сценария.Сгенерировав «производную таблицу», содержащую все даты в текущем месяце (по порядку), затем СЛЕДУЕТ ПОДКЛЮЧИТЬ к ней фактические данные таблицы базы данных и группировать по event_date_start, аналогичные данные можно сгруппировать, полностью подготовить идоставлено в строгом наборе результатов.

Обратите внимание на мой трюк с классом / css с помощью {$row['Day'][0]}day <- <code>[0] означает «отображать только первый символ. Это делает атрибуты класса такими, как Mday, Fday и т. д. Чтобы избежать условной проверки, я назначаю субботам и воскресеньям Sday, чтобы стилизация была простой.

Если вы хотите знать, как выглядит обработанный запрос для этого месяца:

Производная таблица PHP Demo

Я не удосужился добавить неиспользуемые столбцы во время разработки этого решения, но вот данные, которые я использовал для тестирования:

CREATE TABLE IF NOT EXISTS `eventcalendar` (
  `event_description` varchar(255) NOT NULL,
  `event_date_start` date NOT NULL,
  `event_date_end` date NOT NULL,
  `event_type` varchar(255) NOT NULL,
  `swim_club_assigned` varchar(255) NOT NULL,
  PRIMARY KEY (`event_description`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `eventcalendar` (`event_description`, `event_date_start`, `event_date_end`, `event_type`, `swim_club_assigned`) VALUES
('Another Championship one!', '2018-10-11', '2018-10-11', 'GCRSA Championship', 'My Club 2'),
('Another one!', '2018-10-11', '2018-10-11', 'GCRSA Club Meet', 'My Club'),
('Dunno Invitational - Template: Z', '2018-11-12', '2018-11-12', 'GCRSA Championship', ''),
('Preparation Meet (LC) - Template: A', '2018-10-01', '2018-10-01', 'GCRSA Club Meet', 'Gold Coast North SC Inc'),
('Reg Winter Championships (SC) - Template: XY', '2018-10-31', '2018-10-31', 'GCRSA Championship', ''),
('Sprint Meet (LC) - Template: H', '2018-10-11', '2018-10-11', 'GCRSA Club Meet', 'Bond SC Inc');

И вот что он сделал:

enter image description here

...