【问题标题】:Group entries by date and time from timestamps从时间戳中按日期和时间对条目进行分组
【发布时间】:2011-11-28 04:15:28
【问题描述】:

我正在构建一个预订系统,并选择使用时间戳将预订存储在我的 mysql 数据库中。但是,用户可以连续预订 2 或 3 个插槽,例如:

9:00 - 9:30
9:30 - 10:00
10:00 - 10:30

或者他们可以只预订一个插槽。

我想显示用户进行的预订,但按时间范围对它们进行分组,例如,在上面显示的时间中,它应该显示 9:00 - 10:30,而不是列出 3 个项目。

每个预订都与 bookingFrom 和 bookingUntil 一起存储为时间戳。我已经设法让它为 2 个预订工作(例如 9:00-9:30 和 9:30-10:00 仅显示为 9:00-10:00)但如果有一个中间条目,我苦苦思索如何让它发挥作用。

有什么想法吗?我正在使用 PHP/mySQL

表格架构

bookingID、userID、bookingFrom(INT - unix 时间戳)、bookingUntil(INT - unix 时间戳)

    CREATE TABLE IF NOT EXISTS `dma_bookings` (
  `bookingID` int(11) NOT NULL AUTO_INCREMENT,
  `userID` int(11) NOT NULL,
  `bookingFrom` int(11) NOT NULL,
  `bookingUntil` int(11) NOT NULL,
  `roomID` int(11) NOT NULL,
  PRIMARY KEY (`bookingID`),
  KEY `userID` (`userID`,`bookingFrom`,`bookingUntil`),
  KEY `roomID` (`roomID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=98 ;

--
-- Dumping data for table `dma_bookings`
--

INSERT INTO `dma_bookings` (`bookingID`, `userID`, `bookingFrom`, `bookingUntil`, `roomID`) VALUES
(95, 1, 1317362400, 1317364199, 1),
(96, 1, 1317364200, 1317365999, 1),
(97, 1, 1317366000, 1317367799, 1);

到目前为止的代码(道歉非常混乱!):

$bookingArray = $data['bookingInfo'];
        $bookingCleanArray = array();
        $reversedArray = array_reverse($data['bookingInfo']);
        $currentItemIndex=0;
        $nextItemIndex=1;

        foreach($reversedArray as $booking){
            echo "<hr>BookingID: ".$booking['bookingID']."<br/><br/>";

            $bookingFromMinusOne=$booking['bookingFrom']-1;

            if($bookingFromMinusOne==$data['bookingInfo'][$nextItemIndex]['bookingUntil']){

                //The current booking is part of a multiple booking range
                $bookingArray[$nextItemIndex]['bookingUntil']=$booking['bookingUntil'];
                unset($bookingArray[$currentItemIndex]);
            }else{
                echo "Single booking<br/>";
            }

            $currentItemIndex++;
            $nextItemIndex++;

        }

【问题讨论】:

  • 提出一些关于表模式和数据的想法,以及你需要从查询中得到什么结果。
  • 更新了最初的帖子,谢谢!

标签: php mysql date timestamp


【解决方案1】:

假设每次将它们加载到数组中时都有单独的字段,然后使用第一个字符串并计数来查找最后一个字符串。

但是,正如 rahularyansharma 所说,需要更多细节。

好的...嗯 你不就是想抢吗:

SELECT dma_bookings (bookingID, userID, bookingFrom, bookingUntil, roomID) WHERE userID = 1)

这应该给我们:

bookingID、userID、bookingFrom、bookingUntil、roomID

 $bookingArray = array( 95, 1, 1317362400, 1317364199, 1 ),
 array( 96, 1, 1317364200, 1317365999, 1 ),
 array( 97, 1, 1317366000, 1317367799, 1 ),

如果我们...

echo  $bookingArray[][2]; we get '1317362400'
$c = count($bookingArray);
echo $bookingArray[$c][3]; we get '1317367799'

或者我完全误解了你想要做什么?

【讨论】:

  • 感谢斯蒂芬的回复。恐怕问题没有那么直接。考虑 bookings 表中的第四个条目,它与前 3 个条目(95 96 和 97)完全分开,尽管前三个是系列的一部分(您可以看到 bookingID 95 中的 bookingUntil (1317364199) 后跟1317364200 来自 bookingID 96。但是,如果有第四个条目,则在当天晚些时候有一个完全不同的预订 - 例如下午 4 点,它不适用于您的解决方案,因为它会显示从上午 8 点到下午 4 点的预订,其中应该是 8-9:30,然后是 4-4:30
  • 因此,如果边界匹配,我们只会对预订进行分组。例如9 - 10 和 10 - 11 在接触时被分组,但 9 - 10 和 2 - 3 不应该。 (php.net/manual/en/function.sort.php) 但是由于我们在一个多维数组中,我们可能需要一个函数将它们全部洗牌到 2 个数组(开始和结束)中,然后对它们进行排序。我稍后再试一下……午休结束了。
【解决方案2】:

我认为我的方法是选择给定用户的所有预订,但按开始时间排序结果。我感觉你当前的循环有正确的开始,你只需要更多的条件来确保插槽工作。

我会从第一个时段开始,并不断调整结束时间,直到我达到大于当前结束时间的开始时间。此时,您完成了当前插槽(例如将其推送到另一个阵列),并将当前插槽设置为新插槽。

这是一个例子,虽然我没有时间测试它我认为它应该可以工作:

$slots = array(
    array('bookingID' => 95, 'userID' => 1, 'bookingFrom' => 1317362400, 'bookingUntil' => 1317364199, 'roomID' => 1), 
    array('bookingID' => 96, 'userID' => 1, 'bookingFrom' => 1317364200, 'bookingUntil' => 1317365999, 'roomID' => 1), 
    array('bookingID' => 97, 'userID' => 1, 'bookingFrom' => 1317366000, 'bookingUntil' => 1317367799, 'roomID' => 1)
);

$condensed_slots = array();
$currentSlot = null;
foreach($slots as $slot){
    if($currentSlot == null) $currentSlot = $slot;
    else {
        if($slot['bookingFrom'] <= $currentSlot['bookingUntil']){
            $currentSlot['bookingUntil'] = $slot['bookingFrom'];
        }
        else {
            $condensed_slots[] = $currentSlot;
            $currentSlot = $slot;
        }
    }
}

因此,在此之后,$condensed_slots 应该包含一组缩减的插槽(如果可能),尽管 bookingID 可能不一定反映原始的 fromuntil 时间戳(显然)。

【讨论】:

  • 附带说明,在您当前的实现中,您希望在循环运行时小心修改 foreach 循环正在迭代的数组。如果您删除循环尚未到达的索引,您最终可能会遇到各种疯狂的事情。
  • 谢谢你,是的,我后来想到了这一点,我将数据附加到一个新数组中,该数组在迭代的 foreach 循环之外定义和修改。这样我就可以在迭代完成后进行排序和修改,而不必担心任何讨厌的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 2023-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多