如何在没有foreach的情况下显示来自三个表的记录

时间:2016-09-21 17:36:54

标签: php mysql join

我有问题如何进行查询以连接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;

3 个答案:

答案 0 :(得分: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;

然后你的代码看起来像这样:

<?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 :(得分:1)

从我的问题出发,您希望加入这些表格。我认为你应该可以这样做:

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。

答案 2 :(得分:0)

我会完全考虑使用&#39; where_in&#39;而不是向你的数据库投掷大量的查询。

即..

//...

$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中的join命令。 https://www.codeigniter.com/userguide2/database/active_record.html