วิธีแสดงบันทึกจาก 3 ตารางโดยไม่มี foreach

ฉันมีปัญหาในการสอบถามเพื่อรวมบันทึกจาก 3 ตารางและพิมพ์ผลลัพธ์บนหน้าจอ ฉันทำวิธีแก้ปัญหาแล้วแต่ความเร็วไม่ดี และฉันก็มองหาวิธีแก้ปัญหาที่ดีกว่านี้ ตารางของฉันคือ:

ตารางทดสอบ

id_test
testName

ตารางคำถาม

id_quest
id_test
question

ตารางคำตอบ

id_answer
id_quest
answer

การทดสอบทุกครั้งมีคำถาม 7 ข้อ และทุกคำถามมี 10 คำตอบ

จะเขียนแบบสอบถามฐานข้อมูลโดยไม่ต้อง foreach เพื่อแสดงรายการบันทึกนี้บนหน้าจอได้อย่างไร

ฉันทำวิธีแก้ปัญหาเช่นนี้:

    $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;

person Sasa    schedule 21.09.2016    source แหล่งที่มา
comment
ไม่ว่าคุณจะใช้ลูปหรือเขียนสิ่งใดก็ตามที่อยู่ในลูปทุกบรรทัดสำหรับสิ่งที่แบบสอบถามของคุณส่งคืน   -  person Marc B    schedule 21.09.2016
comment
เลยเขียนแบบอื่นที่เขียนไปแล้วไม่ได้เหรอ?   -  person Sasa    schedule 21.09.2016
comment
ใช่ คุณสามารถใช้ while ได้ แต่จำเป็นต้องมีการวนซ้ำ   -  person Phiter    schedule 21.09.2016


คำตอบ (3)


คุณสามารถสร้างแบบสอบถามที่ซับซ้อนมากขึ้นเช่นนี้ เพื่อที่คุณจะต้องเข้าถึงฐานข้อมูลเพียงครั้งเดียว:

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;

จากนั้นโค้ดของคุณจะมีลักษณะดังนี้:

<?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();
person Rebecca Close    schedule 21.09.2016

จากสิ่งที่ฉันได้รับจากคำถามของคุณคุณต้องการเข้าร่วมตาราง ฉันคิดว่าคุณควรจะทำสิ่งนี้ได้:

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 = ?

สิ่งนี้ควรส่งคืนชุดผลลัพธ์ทั้งหมดเป็นวัตถุเดียว แทนที่จะต้องสืบค้น db หลายครั้ง

person bos570    schedule 21.09.2016
comment
ฉันจะจัดเรียง ouput ตาม test_name, คำถาม, คำตอบ หากผลลัพธ์จะต้องถูกประมวลผลเป็นอาร์เรย์อย่างง่ายหรือเอาต์พุตโดยตรงเพื่อรักษาการจัดกลุ่ม - person symcbean; 21.09.2016

ฉันจะพิจารณาใช้ 'where_in' โดยสิ้นเชิงแทนที่จะส่งแบบสอบถามจำนวนมากไปที่ฐานข้อมูลของคุณ

i.e..

//...

$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

ป.ล. ดูคำสั่ง join ใน CI ด้วย https://www.codeigniter.com/userguide2/database/active_record.html

person ajm113    schedule 21.09.2016
comment
หากประสิทธิภาพเป็นปัญหา อย่าใช้where_in ซึ่งจะบังคับให้มีเส้นทางการดำเนินการเฉพาะบนเครื่องมือเพิ่มประสิทธิภาพ db หากคุณพบว่าสิ่งนี้ช่วยให้การค้นหาของคุณเร็วขึ้น แสดงว่าคุณไม่ได้ทำความสะอาดบ้านเลย - person symcbean; 21.09.2016