You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

基于MySQL分组设置表格单元格样式及酒店预订日期屏蔽技术问询

基于MySQL分组实现酒店预订表格单元格样式方案

针对你的酒店预订表场景,核心思路是先通过MySQL获取分组关联信息,再结合PHP和前端实现同预订组(bookingid相同)的单元格统一样式。下面分步骤给出具体可落地的方案:

1. 优化SQL查询,拿到分组关联数据

我们需要同时获取每条夜间记录,以及对应预订组的整体统计信息(比如同预订的日期范围、总天数),这样每条记录都能知道自己所属的分组情况。这里分两种MySQL版本的实现:

方案A(MySQL 8.0+,推荐用窗口函数)

窗口函数可以在不聚合行的前提下,直接给每条记录打上分组标记:

SELECT 
    b.id, 
    b.room, 
    b.night, 
    b.bookingid, 
    b.timestamp,
    -- 同预订的最早/最晚日期
    MIN(b.night) OVER (PARTITION BY b.bookingid) AS booking_start,
    MAX(b.night) OVER (PARTITION BY b.bookingid) AS booking_end,
    -- 同预订的总夜间数,用于合并单元格计算
    COUNT(b.id) OVER (PARTITION BY b.bookingid) AS booking_total_nights
FROM bookings b
-- 保留你原有的年月筛选逻辑
WHERE b.night BETWEEN '$year-$month-01' AND LAST_DAY('$year-$month-01')
ORDER BY b.bookingid, b.night;

方案B(MySQL 5.x兼容,用子查询关联)

如果你的MySQL版本较低,用子查询先统计分组信息再关联原表:

SELECT 
    b.id, 
    b.room, 
    b.night, 
    b.bookingid, 
    b.timestamp,
    bg.booking_start,
    bg.booking_end,
    bg.booking_total_nights
FROM bookings b
JOIN (
    SELECT 
        bookingid,
        MIN(night) AS booking_start,
        MAX(night) AS booking_end,
        COUNT(id) AS booking_total_nights
    FROM bookings
    WHERE night BETWEEN '$year-$month-01' AND LAST_DAY('$year-$month-01')
    GROUP BY bookingid
) bg ON b.bookingid = bg.bookingid
WHERE b.night BETWEEN '$year-$month-01' AND LAST_DAY('$year-$month-01')
ORDER BY b.bookingid, b.night;

⚠️ 重要提醒:一定要用参数绑定(比如PDO的prepare+execute)替代直接拼接变量到SQL里,避免SQL注入风险。

2. PHP端预处理分组数据

拿到查询结果后,把数据按bookingid分组,方便前端渲染时快速识别同组记录:

// 假设$pdo是你的数据库连接实例
$sql = "上面的SQL语句";
$stmt = $pdo->prepare($sql);
// 用参数绑定传递年月,避免注入
$stmt->execute([$year, $month]);
$bookings = $stmt->fetchAll(PDO::FETCH_ASSOC);

// 按bookingid分组
$groupedBookings = [];
foreach ($bookings as $booking) {
    $groupedBookings[$booking['bookingid']][] = $booking;
}

3. 前端表格样式实现(两种常见效果)

效果1:同组行统一背景色

给每个预订组设置交替的背景色,视觉上快速区分不同预订:

<table border="1" cellpadding="8">
    <thead>
        <tr>
            <th>ID</th>
            <th>Room</th>
            <th>Night</th>
            <th>Booking ID</th>
            <th>Timestamp</th>
        </tr>
    </thead>
    <tbody>
        <?php 
        $colorIndex = 0;
        $groupColors = ['#f8f9fa', '#e9ecef']; // 定义两组浅色系背景
        foreach ($groupedBookings as $bookingGroup) {
            $currentColor = $groupColors[$colorIndex % count($groupColors)];
            foreach ($bookingGroup as $row) {
        ?>
        <tr style="background-color: <?php echo $currentColor; ?>">
            <td><?php echo $row['id']; ?></td>
            <td><?php echo $row['room']; ?></td>
            <td><?php echo $row['night']; ?></td>
            <td><?php echo $row['bookingid']; ?></td>
            <td><?php echo $row['timestamp']; ?></td>
        </tr>
        <?php 
            }
            $colorIndex++;
        }
        ?>
    </tbody>
</table>

效果2:合并同组重复列(比如Room、Booking ID)

利用SQL里拿到的booking_total_nights,实现同预订组的Room和Booking ID单元格合并,让表格更简洁:

<table border="1" cellpadding="8">
    <thead>
        <tr>
            <th>ID</th>
            <th>Room</th>
            <th>Night</th>
            <th>Booking ID</th>
            <th>Timestamp</th>
        </tr>
    </thead>
    <tbody>
        <?php 
        foreach ($groupedBookings as $bookingGroup) {
            $isFirstRow = true;
            foreach ($bookingGroup as $row) {
                $rowspan = $isFirstRow ? $row['booking_total_nights'] : 0;
        ?>
        <tr>
            <td><?php echo $row['id']; ?></td>
            <?php if ($isFirstRow): ?>
            <td rowspan="<?php echo $rowspan; ?>"><?php echo $row['room']; ?></td>
            <?php endif; ?>
            <td><?php echo $row['night']; ?></td>
            <?php if ($isFirstRow): ?>
            <td rowspan="<?php echo $rowspan; ?>"><?php echo $row['bookingid']; ?></td>
            <?php endif; ?>
            <td><?php echo $row['timestamp']; ?></td>
        </tr>
        <?php 
                $isFirstRow = false;
            }
        }
        ?>
    </tbody>
</table>

内容的提问来源于stack exchange,提问作者Salwa El Bannan

火山引擎 最新活动