我想存储和检索一个完全不依赖于实际日期的动态每周计划。
数据将存储在这样的MySQL表中(不按时间排序):
(Class和Instructor列将存储其他表的引用ID,但我在此处使用实际名称以便于一目了然)
----------------------------------------------------------------------
| id | time | dayofweek | class | instructor |
----------------------------------------------------------------------
| 1 | 6:30a | 1 | Zumba | Julie |
----------------------------------------------------------------------
| 2 | 9:00a | 3 | Kickbox | Devon |
----------------------------------------------------------------------
| 3 | 11:00a | 4 | Zumba | Alex |
----------------------------------------------------------------------
| 4 | 6:30a | 4 | Dance | Karen |
----------------------------------------------------------------------
| 5 | 5:00p | 1 | R-BAR | Karen |
----------------------------------------------------------------------
| 6 | 5:00p | 6 | Dance | Karen |
----------------------------------------------------------------------
| 7 | 9:00a | 7 | Kinder | Julie |
最终输出在视觉上看起来像这样(按时间排序):
---------------------------------------------------------
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
-------------------------------------------------------------------
| 6:30a | Zumba | | | Dance | | | |
-------------------------------------------------------------------
| 9:00a | | |Kickbox| | | |Kinder |
-------------------------------------------------------------------
| 11:30a | | | | Zumba | | | |
-------------------------------------------------------------------
| 5:00p | R-BAR | | | | | Dance | |
-------------------------------------------------------------------
但我无法有效地解决如何有效完成这项工作的问题。我今天已经在谷歌搜索了几个小时,并且发现了一些看起来可能有用的帖子,但它们从来都不是我想要的。
我开始考虑通过一个函数或其他方式为每个时间段的7天中的每一天运行一个单独的查询,但这对于这样一个简单的任务来说是非常草率和太多的查询。显然,所有7天(列)将始终显示,但可以随时添加或删除时隙(行),具体取决于当时是否有事件。
接下来,我研究了将所有内容存储在一个数组中并将所有行重复一次,然后逐个处理它们的日期。我不确定我会如何动态地做到这一点......
我找到了这个例子,我觉得它非常接近我需要的东西: PHP - Merge duplicate array keys in a multidimensional array
毕竟说完了,我打算为用户创建一个简单的管理页面来添加或删除事件。有什么想法吗?
答案 0 :(得分:1)
我建议采用以下方法:
SELECT DISTINCT time FROM table;
SELECT DISTINCT dayofweek FROM table;
SELECT * FROM table;
使用星期几构建列。 (第二查询结果)
对于表格的每个单元格(不包括第1行和第1列),请使用
foreach($result /* of 3rd query */ as $row){
if(($row['time'] == $celltime) && ($row['day'] == $cellday)){
// show formatted row
// remove row from result buffer, so it should never appear again
// also row removement would increase speed for further search
} else {
// ignore or something
}
}
好的方法是根据time
和dayofweek
构建每个小区ID,例如'cell-9:00a-3'
或'cell-11:00a-4'
(带id.split('-').slice(1)
),这样您就可以使用javascript /在运行时提取单元格的数据,或者通过ajax进一步提交。
Eather,我建议将桌子标准化,将其分成3-4个或更多(如果需要):
UN
=无符号,NN
=非空,AI
= AUTO_INCREMENT
。
<强> 优点: 强>
DISTINCT
个数据列,因为它们是分开的。您可以通过小区ID轻松访问值,例如'cell-1-2-3-4'
,
list(, $timeId, $dayId, $classId, $instructorId) = explode('-', $_POST['cell']);
如果,您将发布您要修改的地点或内容。
VARCHAR()
或字符串数据的重复次数较少。ON CASCADE DELETE
可能配置了FK_Schedule_Time
。等...
<强> UPDv1:强>
好吧,让我们试着想象一下我的意思:
我的意思是,要显示时间表(或任何其他数据透视表),您应该获得标签行/列的不同值,即日期名称/数字或时间。然后构建一个表,其中包含thouse不同的值,作为绘图的X / Y.然后,寻找[X:Y]交叉点(如图上的点) - 它们将是数据透视。
我写过的一个时间表花了我3个月的时间。我不会说,它现在是完美的,但它确实有效。尝试简化您的任务:拆分为较小的任务。然后你会看到更大的图片。
答案 1 :(得分:1)
$a=array();
$a[] = array( 'id'=>'1' ,'time'=>'6:30a' , 'dayofweek'=>'2' , 'class'=>'Zumba');
$a[] = array( 'id'=>'2' ,'time'=>'6:40a' , 'dayofweek'=>'3' , 'class'=>'Zumba');
$a[] = array( 'id'=>'2' ,'time'=>'6:20a' , 'dayofweek'=>'3' , 'class'=>'Zumba');
$a[] = array( 'id'=>'2' ,'time'=>'1:20p' , 'dayofweek'=>'3' , 'class'=>'Zumba');
$new_array=array();
foreach($a AS $k =>$v){
if(!array_key_exists($v['time'],$new_array)){
$new_array[$v['time']]=array("","","","","","","","");
unset($new_array[$v['time']][0]);
}
$new_array[$v['time']][$v['dayofweek']]=$v['class'];
}
function cmp($a, $b)
{
$a = preg_replace('{\:}', '', $a);
$a = preg_replace('{a}', '', $a);
$a = preg_replace('{(.*?)p}', '100$1', $a);
$a = (int)$a;
$b = preg_replace('{\:}', '', $b);
$b = preg_replace('{a}', '', $b);
$b = preg_replace('{(.*?)p}', '100$1', $b);
$b = (int)$b;
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
uksort($new_array, "cmp");
$weekmap = array( '','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
print_r($new_array);
foreach($new_array AS $k =>$v){
echo $k.'::';
foreach($v AS $k1 =>$v1){
//echo $weekmap[$k1];
//echo '->';
if($v1==''){
echo 'null';
}
echo $v1;
echo '|';
}
echo PHP_EOL;
}
输出
Array
(
[6:20a] => Array
(
[1] =>
[2] =>
[3] => Zumba
[4] =>
[5] =>
[6] =>
[7] =>
)
[6:30a] => Array
(
[1] =>
[2] => Zumba
[3] =>
[4] =>
[5] =>
[6] =>
[7] =>
)
[6:40a] => Array
(
[1] =>
[2] =>
[3] => Zumba
[4] =>
[5] =>
[6] =>
[7] =>
)
[1:20p] => Array
(
[1] =>
[2] =>
[3] => Zumba
[4] =>
[5] =>
[6] =>
[7] =>
)
)
6:20a::null|null|Zumba|null|null|null|null|
6:30a::null|Zumba|null|null|null|null|null|
6:40a::null|null|Zumba|null|null|null|null|
1:20p::null|null|Zumba|null|null|null|null|
http://sandbox.onlinephpfunctions.com/code/8da03b1833f58e7f60888cfcfb6e544cd3ff10ad