如何使用php对id进行分组并内联日期

时间:2016-11-15 15:05:46

标签: php mysql loops

这是我的示例代码,我想分组ID并内联日期,如下图所示

 $sql_e = mysqli_query($link,"SELECT * FROM tbl_attendees");
 while($sql_e_res = mysqli_fetch_array($sql_e)){
    echo'<tr>
    <td>'.$sql_e_res['s_usn'].'</td>
    <td>'.$sql_e_res['s_name'].'</td>
    ';
    $dt = ''.$sql_e_res['at_date'].'';
    $dt = strtotime(str_replace(',', '', $dt));
    $d = date('j',$dt);

    $currentdays = intval(date("t"));
    $i = 0;
    while ($i++ < $currentdays){
        if($i == $d){
            $ff='<td style="text-align:center">'.$d.'</td>';            
        }else{
            $ff='<td style="text-align:center">';
        }
            echo $ff;
    }
        echo'</tr>';                                                    
    }

Original

What i want

2 个答案:

答案 0 :(得分:1)

更改

SELECT * FROM tbl_attendees 

SELECT * FROM tbl_attendees order by s_usn asc, at_date asc

或使用s_name asc代替s_usn asc,具体取决于您是希望按ID的顺序还是按名称顺序显示结果。

您处理的控制中断逻辑会在处理完给定ID的所有日期时创建新的html行。但是,由于您的ID和日期不是任何顺序,由于结果集缺乏顺序,您很快就会突破逻辑。理想情况下,您希望一起订购ID,然后一起订购日期,以便按顺序处理它们。这是通过order by完成的,如上所示。

如果你必须在数据库层进行....(但我不推荐)

SELECT s_usn, s_name, 
    max(case when extract(day from at_date)=1 then 'X' end) as 1,
    max(case when extract(day from at_date)=2 then 'X' end) as 2,
    max(case when extract(day from at_date)=3 then 'X' end) as 3,
    max(case when extract(day from at_date)=4 then 'X' end) as 4,
    max(case when extract(day from at_date)=5 then 'X' end) as 5,
    max(case when extract(day from at_date)=6 then 'X' end) as 6,
    max(case when extract(day from at_date)=7 then 'X' end) as 7,
    max(case when extract(day from at_date)=8 then 'X' end) as 8,
    max(case when extract(day from at_date)=9 then 'X' end) as 9,
    max(case when extract(day from at_date)=10 then 'X' end) as 10,
    max(case when extract(day from at_date)=11 then 'X' end) as 11,
    max(case when extract(day from at_date)=12 then 'X' end) as 12,
    max(case when extract(day from at_date)=13 then 'X' end) as 13,
    max(case when extract(day from at_date)=14 then 'X' end) as 14,
    max(case when extract(day from at_date)=15 then 'X' end) as 15,
    max(case when extract(day from at_date)=16 then 'X' end) as 16,
    max(case when extract(day from at_date)=17 then 'X' end) as 17,
    max(case when extract(day from at_date)=18 then 'X' end) as 18,
    max(case when extract(day from at_date)=19 then 'X' end) as 19,
    max(case when extract(day from at_date)=20 then 'X' end) as 20,
    max(case when extract(day from at_date)=21 then 'X' end) as 21,
    max(case when extract(day from at_date)=22 then 'X' end) as 22,
    max(case when extract(day from at_date)=23 then 'X' end) as 23,
    max(case when extract(day from at_date)=24 then 'X' end) as 24,
    max(case when extract(day from at_date)=25 then 'X' end) as 25,
    max(case when extract(day from at_date)=26 then 'X' end) as 26,
    max(case when extract(day from at_date)=27 then 'X' end) as 27,
    max(case when extract(day from at_date)=28 then 'X' end) as 28,
    max(case when extract(day from at_date)=29 then 'X' end) as 29,
    max(case when extract(day from at_date)=30 then 'X' end) as 30,
    max(case when extract(day from at_date)=31 then 'X' end) as 31
FROM tbl_Attendees
WHERE extract(month from at_date) = 11 --set up a variable 
      extract(year from at_date)  = 2016 --setup as variable 
GROUP BY S_usn, s_name
ORDER BY s_usn asc

我们需要where子句(或类似的子句)以确保我们一次只能处理1个月...如果您需要一个涉及多个月的轮换期,则两者之间会有效;但你的内部php while循环可能不支持没有更改。

Link for extract usage

这假设学生一年中每个月每天只能有1条记录。如果存在多条记录,它们将被合并,因为我不知道这在使用方面意味着什么。

答案 1 :(得分:1)

正如xQbert所说,您需要按s_usn

对查询进行排序

编辑:我的代码期望处理的查询是"SELECT * FROM tbl_attendees ORDER BY s_usn asc;"

<小时/> 我想这段代码有机会进行更优化,但我试图让我的编码风格与你的编码风格非常接近,并重用你的var名称。我还试图将代码可读性作为优先事项。尝试这个代码,我几乎评论了一切

代码是关于一个大循环抛出结果行,并且对于每一行,您将检查这是否是新学生。如果是新学生,那么您将使用名为$daysTDs的字符串构建上一个学生的与会者日期"<td>1<td><td><td><td>3<td>...."

我们将从名为$attendees的数组中构建此字符串,该数组包含此学生参与其中的所有日期,它可能看起来像这样

  $attendees = [12,10]

当我们遇到一个新学生时,我们将回复前一个学生的$daysTDs并在循环结束后按</tr>关闭行,我们也将回复最后一个学生{{ 1}}字符串并按$daysTDs

关闭它的行
</tr>

检查代码并告诉我它是否得到了所需的结果