在MySQL中如何最好地获得具有多个子项的记录集

时间:2014-04-08 10:57:05

标签: php mysql

假设我有一个代表事件的表,主键为event_ID。数据可能是event_nameevent_locationevent_date

然后我有一个代表与会者的表,主键为attendee_ID。数据可能是first_namelast_namecontact_number

我有一个链接表,它使用event_IDattendee_ID作为外键。

现在我需要查询这个。我想在两个给定日期之间返回一组记录事件。我还需要查看每个活动的与会者。

我将使用PHP将这些记录映射到一个对象。我期待的是:

array(
    // Multiple `events`
    array(
        'event_ID' => 1,
        'event_location' => 'London',
        'event_start' => '2014-11-27',
        'attendees' => array(
            // multiple `attendees`
            array(
                'attendee_ID' => 1,
                'first_name' => 'John'
                'last_name' => 'Smith',
                'contact_number' => '0207 123 1234',
            ),
            ...
        ),
    ),
    ...
);

我尝试过谷歌搜索,但想不出如何表达我在搜索词中需要实现的目标。我想我需要查询heirachical数据。

我不想做的是获取一组记录事件,然后通过它们进行迭代,进行更多数据库调用以填充与会者,因为这看起来非常低效。

我想到的另一个想法是获取所有事件记录,然后查询链接表,整理与会者ID并查询与会者表以查找与会议匹配的任何内容,并使用PHP代码将其与我的事件重新关联我从记录集构建的对象。

是否有更优雅,最佳的实践方法来实现这一目标?

2 个答案:

答案 0 :(得分:0)

我假设您在attendees表上有一列用于指定参与的事件用户。这称为attended_event_ID。通过使用此功能,您可以使用以下功能执行此操作;

<?php

  $query =  "SELECT e.event_ID, e.event_location, e.event_start,
             a.attendee_ID, a.first_name, a.last_name, a.contact_number, a.attended_event_ID
             FROM events e
             LEFT JOIN attendees a ON a.attended_event_ID = e.event_ID
             ORDER BY e.event_ID";
  $result = $db->query($query);
  while($row = $result->fetch_assoc()){
    $events[$row["event_ID"]]["event_ID"] = $row["event_ID"];
    $events[$row["event_ID"]]["event_location"] = $row["event_location"];
    $events[$row["event_ID"]]["event_start"] = $row["event_start"];
    $events[$row["event_ID"]]["attendees"][] = array(
                                                    "attendee_ID" => $row["attendee_ID"],
                                                    "first_name" => $row["first_name"],
                                                    "last_name" => $row["last_name"],
                                                    "contact_number" => $row["contact_number"]
                                                );
  }        

?>

答案 1 :(得分:0)

select 
    event . *,
    CONCAT('[',
            GROUP_CONCAT(CONCAT('{"name":"',
                        attendees.name,
                        '", id:"',
                        attendees.id,
                        '"}')),
            ']') attendees
FROM
    `event`
        LEFT JOIN
    attendees ON attendees.event = event.id
GROUP BY event.id

将以以下格式返回您的结果

1   event2  [{"name":"name-1-1", id:"6142"},{"name":"name-1-1", id:"2048"},{"name":"name-1-1", id:"1"},{"name":"name-1-1", id:"4095"}]
2   event3  [{"name":"name-2-2", id:"2"},{"name":"name-2-2", id:"4096"},{"name":"name-2-2", id:"6143"},{"name":"name-2-2", id:"2049"}]
3   event4  [{"name":"name-3-3", id:"6144"},{"name":"name-3-3", id:"2050"},{"name":"name-3-3", id:"3"},{"name":"name-3-3", id:"4097"}]
4   event5  [{"name":"name-4-4", id:"4"},{"name":"name-4-4", id:"4098"},{"name":"name-4-4", id:"6145"},{"name":"name-4-4", id:"2051"}]
5   event6  [{"name":"name-5-5", id:"6146"},{"name":"name-5-5", id:"2052"},{"name":"name-5-5", id:"5"},{"name":"name-5-5", id:"4099"}]
6   event7  [{"name":"name-6-6", id:"6"},{"name":"name-6-6", id:"4100"},{"name":"name-6-6", id:"6147"},{"name":"name-6-6", id:"2053"}]

与会者结果是有效的JSON,可以使用JSON_DECODE进行解码。

确保您拥有索引这在2000多个活动和8000多名与会者

上的工作时间为0.047秒