0

基本的に、私は3つのテーブルを持っています。プロジェクト テーブル、質問テーブル、回答テーブルがあります。プロジェクトには多くの質問があり、質問には多くの回答がある場合があります。質問 ID で 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']
        ));
      }          
    }
4

1 に答える 1

0

1 つのクエリで、すべての回答を要求し、それらに質問を結合し、プロジェクトを質問に結合できます。

  1. 空の配列を作成$projects = array()
  2. 結果のすべての行を反復するforeach ($rows as $row)
  3. プロジェクトが存在しない場合は、そのデータを含むプロジェクトを配列に追加します (プロジェクト ID をキーとして使用します)。if (!isset($projects[$row->project_id])) { $projects[$row->project_id] = array('col1' => $row->col1,'questions' => array()); }
  4. まだ存在しない場合は、データを含む質問をプロジェクトの質問配列に追加します (質問 ID をキーとして使用します)。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. 回答とそのデータをプロジェクトの質問回答配列に追加します (回答 ID をキーとして使用)$projects[$row->project_id]['questions'][$row->question_id]['answers'][$row->answer_id] = array('col3' => $row->col3);

しかし、おわかりのように、そのクエリでは多くの役に立たない情報が得られます。1 つのクエリでプロジェクトのみを取得し、それらを反復処理し、各サイクルでデータを配列に追加して再度クエリを実行し、特定の project_id を持つ質問を取得し、それらを反復処理して、各サイクルでデータを配列に追加し、再度クエリを実行して回答を取得できます。特定の question_id を持ち、それらを繰り返し処理し、配列にデータを追加します。

しかし、これを再考すると、大量の役に立たないデータ (つまり、プロジェクトと質問に関するデータの繰り返し) を返す場合でも、MySQL は PHP よりも高速に動作し、1 つのクライアントから 1 つのクエリと 50 のクエリを比較する方がはるかに優れていると思います。最初の方法を使用することをお勧めします。

データベースのテーブルと列に関する詳細情報がなければ、疑似コード アルゴリズム以上のものは得られません。

編集:可能な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 | 質問 | 質問者 | プロジェクト ID |
  • 答え -> | ID | 答え | 回答者 | 質問ID |
于 2013-11-08T21:42:02.577 に答える