2013-11-08 5 views
0

В принципе, у меня есть три таблицы. У меня есть таблица проектов, таблица вопросов и таблица ответов. У проекта может быть много вопросов, и у вопроса может быть много ответов. Использование ПДО и LEFT JOIN по вопросу ID, как я могу включить комментарии с ответами в многомерный массив так, что структура будет выглядеть следующим образом:PHP PDO LEFT JOIN Многомерный массив

[Question] => Array 
    (
     [id] => 1 
     [question] => 'Random Question' 
     [askedBy] => 123 
     [answer] => Array 
      (
       [0] => Array 
       (
        [id] => 1 
        [answer] => 'An Answer' 
        [answeredBy] => 123 
       ) 
       [1] => Array 
       (
        [id] => 1 
        [answer] => 'Another Answer' 
        [answeredBy] => 123 
       ) 
      ) 
    ) 

ФИНАЛИЗИРОВАН код (который возвращается то, что я хочу)

$questions = array(); 
$questionCounter = 0; 
$questionID = NULL; 


$STH = $DBH->query("SELECT `project_question`.`id` AS question_id, `project_question`.`question`, `project_question`.`userID` AS askedBy, 
           `project_question`.`created` AS question_created, `project_answer`.`id` AS answer_id, 
           `project_answer`.`answer`, `project_answer`.`userID` AS answeredBy, 
           `project_answer`.`accepted`, `project_answer`.`created` AS answer_created 
          FROM `project_question` 
        LEFT JOIN `project_answer` 
          ON `project_question`.`id` = `project_answer`.`questionID` 
         WHERE `project_question`.`projectID` = $args[0] 
          AND `project_question`.`projectPhase` = 2"); 

    while($row = $STH->fetch(PDO::FETCH_ASSOC)){ 
     if($row['question_id'] !== $questionID){ 
     $questions[$questionCounter] = array(
      'id' => $row['question_id'], 
      'question' => $row['question'], 
      'userID' => $row['askedBy'], 
      'created' => $row['question_created'], 
      'answers' => array()     
     ); 
     array_push($questions[$questionCounter]['answers'], 
      array(
       'id' => $row['answer_id'], 
       'answer' => $row['answer'], 
       'userID' => $row['answeredBy'], 
       'accepted' => $row['accepted'], 
       'created' => $row['answer_created'] 
     )); 
     $questionCounter++; 
     $questionID = $row['question_id']; 
     } else { 
     array_push($questions[$questionCounter - 1]['answers'], 
      array(
       'id' => $row['answer_id'], 
       'answer' => $row['answer'], 
       'userID' => $row['answeredBy'], 
       'accepted' => $row['accepted'], 
       'created' => $row['answer_created'] 
     )); 
     }   
    } 
+0

Возможно, вам будет лучше с несколькими запросами. Используйте один, чтобы получить вопросы, затем еще один, чтобы получить ответы на каждый вопрос. –

+0

Что предлагает @RocketHazmat, не является хорошей альтернативой, потому что вы значительно увеличиваете нагрузку на MySQL. Это может привести к увеличению времени отклика, особенно. если база данных и веб-сервер не находятся на одном сервере. – Gajus

ответ

0

В одном запросе вы можете запросить ответы на все вопросы, присоединиться к ним и присоединиться к проектам.

  1. Создать пустой массив $projects = array()
  2. перебирать все результирующей строки foreach ($rows as $row)
  3. Добавить проект с его данными в массив, если он уже не существует (используйте идентификатор проекта в качестве ключа) if (!isset($projects[$row->project_id])) { $projects[$row->project_id] = array('col1' => $row->col1,'questions' => array()); }
  4. Добавить вопрос с его данные для массива вопросов проекта, если он еще не существует (используйте ключ вопроса как ключ) if (!isset($projects[$row->project_id]['questions'][$row->question_id])) { $projects[$row->project_id]['questions'][$row->question_id] = array('col2' => $row->col2,'answers' => array()); }
  5. Добавить ответ с его данными в проект ответа на вопрос массив (использовать идентификатор ответа как ключ) $projects[$row->project_id]['questions'][$row->question_id]['answers'][$row->answer_id] = array('col3' => $row->col3);

Но, как вы можете понять, в этом запросе вы получите много ненужной информации. Вы можете пойти с одним запросом, получить только проекты, пройти через них, в каждом цикле добавить данные в массив и запросить еще раз, чтобы получить вопросы, которые имеют конкретный project_id, итерации через них, в каждом цикле добавить данные в массив и запросить еще раз, чтобы получить ответы который имеет конкретный question_id, итерацию через них и добавление данных в массив.

Но если я переосмысливаю это, я думаю, что MySQL будет работать быстрее, чем PHP, даже с возвращением пустых бесполезных данных (я имею в виду, повторяю данные о проектах и ​​вопросах) и 1 запрос и возможные 50 запросов от одного клиента намного лучше , поэтому я предлагаю лучше использовать первый метод.

Без дополнительной информации о вашей таблице и столбцах базы данных вы не получите от меня ничего больше, чем псевдокодовый алгоритм.

EDIT: Возможно MySQL выберите запрос:

SELECT 
    a.id answer_id, a.answer, a.answeredBy, 
    q.id question_id, q.question, q.askedBy, 
    p.id project_id, p.title 
FROM answer a 
LEFT JOIN question q ON q.id = a.question_id 
LEFT JOIN project p ON p.id = q.project_id 

Для структуры таблицы

  • проект -> | id | название |
  • вопрос -> | id | вопрос | askBy | project_id |
  • ответ -> | id | ответ | Ответить | question_id |
+0

Мне нравится этот код, и я почти получил его работу, но мне было интересно, если мы сделаем его более эффективным, установив переменную, содержащую идентификатор вопроса, и создадим новый вопрос, если он изменится, а не проверяет массив каждый раз чтобы узнать, установлено ли что-то – Neve12ende12

+0

@JohnHargis. Он уже установлен, чтобы держать question_id как ключ массива. Необходимо проверить, существует ли вопрос, потому что вы можете перезаписать существующий вопрос пустым массивом ответов. – Deele

+0

Я добавлю свой последний код к вопросу, минус таблицу проекта. Дайте мне знать, есть ли способ, которым это может сломаться. – Neve12ende12

Смежные вопросы