2016-09-21 11 views
0

3つのテーブルからレコードを結合し、結果を画面に出力する方法は問題があります。私は解決策を作ったが、スピードには不向きであり、より良い解決策を模索してきた。私のテーブルは以下のとおりです。foreachなしで3つのテーブルからレコードを表示する方法

テストテーブル

id_test 
testName 

質問表

id_quest 
id_test 
question 

回答テーブル

id_answer 
id_quest 
answer 

すべてのテストには7つの質問があり、すべての質問には10の回答があります。

このレコードを画面に表示するにはforeachなしでデータベースクエリを書き込むにはどうすればよいですか?私は完全に使用して「where_in」の代わりに、あなたのデータベースにクエリのトンを投げになり

$this->db->select('id_test,testName,description,time,type,sum'); 
    $this->db->where('id_test',$idTest); 
    $query['test'] = $this->db->get('tests')->result()[0]; 

    $this->db->select('id_quest,inquiry'); 
    $this->db->where('id_test',$idTest); 
    $query['questions'] = $this->db->get('questions')->result(); 

    $i=0; 
    foreach ($query['questions'] as $question) { 
     $this->db->select('id_answer,response,value'); 
     $this->db->where('id_quest',$question->id_quest); 
     $query['questions'][$i]->answer = $this->db->get('answer')->result(); 
     $i++; 
    } 
    return $query; 
+1

ループを使用するか、クエリーが返すものについてループ内のすべての行を書き出します。 –

+0

私は既に書いた別の方法で書くことはできませんか? – Sasa

+1

はい、whileを使用できますが、ループは必須です。 – Phiter

答えて

0

私はこのようなソリューションを作りました。パフォーマンスは依然として大きな問題である。また場合

すなわち..

//... 

$this->db->select('id_quest,inquiry'); 
$this->db->where('id_test',$idTest); 
$query['questions'] = $this->db->get('questions')->result(); 

$questionIds = array(); 

foreach($query['questions'] as $question) 
    $questionIds[] = $question->id_quest; 

$this->db->select('id_answer,response,value'); 
$this->db->where_in('id_quest', $questionIds); 
$answers = $this->db->get('answer')->result(); 

$i=0; // <<< Idk what the main purpose of this is, 
     //  but you do know you can simply use '[]' appending to an array, right? 
foreach ($answers as $answer) { 
    $query['questions'][$i]->answer = $answer; 
    $i++; 
} 

。キャッシュに目を通す。 CodeIgniterはこれを非常にうまくサポートします。

https://www.codeigniter.com/userguide3/libraries/caching.html

P.Sはまた、CIに参加するコマンドに見えます。 https://www.codeigniter.com/userguide2/database/active_record.html

+1

パフォーマンスに問題がある場合は、where_inを使用しないでください。これにより、dbオプティマイザで特定のエクセス・パスが強制されます。あなたがあなたの質問をスピードアップするためにこれを見つけたなら、おそらく家事をしていないでしょう。 – symcbean

1

あなたは一度だけのデータベースをヒットする必要がありようにするには、このような、より複雑なクエリを行うことができますから、

<?php 
// your database info here 
$db_host = ''; 
$db_user = ''; 
$db_pass = ''; 
$db_name = ''; 

$con = mysqli_connect($db_host,$db_user,$db_pass,$db_name); 
if($con->connect_error) 
    die('Connect Error (' . mysqli_connect_errno() . ') '. mysqli_connect_error()); 

$query = "SELECT 
t.id_test, t.testName, t.description, t.time, t.type, t.sum, 
q.id_quest, q.inquiry, 
a.id_answer, a.response, a.value 
FROM tests AS t 
LEFT JOIN questions AS q ON q.id_test = t.id_test 
LEFT JOIN answers AS a ON a.id_quest = q.id_quest 
WHERE t.id_test = ?"; 

if (!$stmt = $con->prepare($query)) 
    die('Prepare Error: ' . $con->error); 

$idTest = 2; 
if (!$stmt->bind_param('i', $idTest)) 
    die('Bind Parameters Error ' . $stmt->error); 

if (!$stmt->execute()) 
    die('Select Query Error ' . $stmt->error); 

while ($stmt->fetch()) 
{ 
// get each resulting answer row, complete with associated question id and test id 
} 
$stmt->close(); 
$con->close(); 
1

SELECT 
t.id_test, t.testName, t.description, t.time, t.type, t.sum, 
q.id_quest, q.inquiry, 
a.id_answer, a.response, a.value 
FROM tests AS t 
LEFT JOIN questions AS q ON q.id_test = t.id_test 
LEFT JOIN answers AS a ON a.id_quest = q.id_quest 
WHERE t.id_test = $idTest; 

を次に、あなたのコードは次のようになります私はあなたの質問のうちあなたがテーブルに加わることを探しているものを得ます。

SELECT test_table.test_name, 
     qestion_table.question, 
     answer_table.answers 
FROM test_table 
INNER JOIN questions_table 
on questions_table.id_test = test_table.id_test 
INNER JOIN answers_table 
ON answers_table.id_quest = questions_table.id_quest 
WHERE test_table.id_test = ? 

これはむしろデシベル数回を照会することよりも、1つのオブジェクトとして結果セット全体を返す必要があります:私はあなたがこのような何かを行うことができるはずだと思います。

+1

私はまた、結果を単純な配列として処理するか、またはグループ化を維持するために直接出力するかどうかをtest_name、question、answersによって出力をソートします。 – symcbean

関連する問題