我在高效打印考勤表时遇到了麻烦。可能有一个术语来描述这种情况,但我不知道它是什么,所以我在寻找解决方案时遇到了麻烦。数据透视表很接近,但还不够。
我有一个MySQL数据库布局如下(简化):
Log_events(event_id, event_name, ...)
Log_members(member_id, member_name, ...)
Log_attendance(member_id, event_id, ...)
Log_events包含事件的所有数据,Log_members包含每个成员的所有数据,Log_attendance包含每个成员每次参加事件的双id条目。
我试图打印出一个表(HTML表与PHP),其中所有的事件作为列,然后所有的成员作为行。然后,使用log_attendance表,我将在每个成员参加活动的表单元格中打印一个标记或一些信息,类似于:
<>之前名称| Event1 | Event2 | Event3----------------------------------Member1 | X | X | XMember2 | | X |成员3 | X | | X之前我有麻烦弄清楚如何做到这一点没有一个可笑的嵌套查询的数量。我该如何有效地做到这一点?
下面是我想打印出来的一个例子:http://www.worldoflogs.com/guilds/30890/character/
我认为最好的方法是对每个不同的事件进行查询,并检索参加该事件的成员:
$result=$mysqli->query("SELECT event_id, event_name from Log_events");
while($row=$result->fetch_array()){
$query="SELECT member_name FROM Log_attendance
JOIN Log_members ON Log_members.member_id=Log_attendance.member_id
WHERE Log_attendance.event_id='$row[0]'
";
$res2=$mysqli->query($query);
while($member_row=$res2->fetch_array()){
//Do something with the info. Like store it so you can format the table later.
}
}
根据你想打印的表格,你可以使用其他方式:
获取成员列表,然后检索他们参加的事件。
我设法使它工作。从Clockwork-Muse发布的链接中,我找到了MySQL函数GROUP_CONCAT。
我的查询现在看起来像这样:
SELECT a.member_id, p.member_name, c.*
FROM Log_attendance a NATURAL JOIN Log_events r NATURAL JOIN Log_players p
LEFT JOIN (
SELECT a2.member_id pid, GROUP_CONCAT(a2.event_id) all_events
FROM Log_attendance a2
) c ON c.pid=a.member_id
GROUP BY a.member_id
(如果有错误,那是因为我不得不手工编辑)
基本上,它将所有事件id连接到每个成员的"1,2,3,5,9"这样的字符串中。在PHP中,我首先检索所有事件,打印列,并将该列表字符串与列的id进行比较。我有其他的WHERE语句来限制结果的大小,所以它不会变得太慢。