你们如何从两个或多个表中获取数据并在codeigniter中操作它?
假设我们有2个表格的问题和答案。一个问题可以有一个或多个答案。现在让我们假设一个答案可以有喜欢和不喜欢。你们如何得到所有问题的答案,以便在视图中显示它们?我会告诉你我的解决方案,但我很好奇你的。
我使用像这样的库:
class Questions_library {
var $CI = &get_instance();
function get_questions_with_answers(){
$data = array();
$questions = $this->CI->questions_model->get_questions();
if ($questions):
foreach ($questions as $q):
$temp = array();
$temp = $q;
$temp['answers'] = $this->CI->answerslibrary->get_answers($q['id']);
$data[] = $temp;
endforeach;
endif;
return $data ? $data : false;
}
}
现在在答案库中,我可以采取相同的方法来得到答案,并回答和不喜欢。
我的方法中的一个缺点是,如果我想用分数或喜欢/不喜欢等分类来显示我的问题,我必须在我的模型中使用连接或嵌套查询,并且我可以利用我的图书馆。
您如何管理此任务?
答案 0 :(得分:2)
正如@nevermind指出的那样,唯一的方法是在SQL中使用JOIN
。你所做的任何PHP循环数据都将成为PHP和MySQL的瓶颈。使用JOIN
的唯一查询,您将获得所有结果,(使用GROUP BY
子句与SUM
和COUNT
获取元素的数量)和您将能够使用ORDER BY
。并且您只对DDBB使用查询,而使用您的方法,您使用大量查询(每行1个)来获得相同的结果。相信我,我已经看到了你在上面提出的系统中的代码,它就像一件紧身衣。
如果您想获得有关使用MySQL子句的更多帮助,请发布您的代码,我会指出如何操作。
让我们尝试一下SQLFiddle:
起点:两个表,问答,具有以下结构:
CREATE TABLE IF NOT EXISTS `answer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`question_id` int(11) DEFAULT NULL,
`title` tinytext COLLATE utf8_spanish_ci,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
INSERT INTO `answer` (`id`, `question_id`, `title`) VALUES
(1, 1, 'a1'),
(2, 1, 'a2'),
(3, 1, 'a3'),
(4, 1, 'a4'),
(5, 1, 'a5'),
(6, 2, 'a3'),
(7, 2, 'a2'),
(8, 2, 'a1');
CREATE TABLE IF NOT EXISTS `question` (
`id` int(11) DEFAULT NULL,
`title` tinytext COLLATE utf8_spanish_ci,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
INSERT INTO `question` (`id`, `title`) VALUES
(1, 'question 1'),
(2, 'question 2');
http://sqlfiddle.com/#!2/400994/6
如您所见,在小提琴中,我们得到INNER JOIN
的正确数据,与两个表的JOIN一样多。
使用GROUP BY
和LIMIT
,我们可以获得所有值,无需担心:
SELECT
q.id qId
, q.title qTitle
, GROUP_CONCAT( a.id SEPARATOR " ")
FROM question q
INNER JOIN answer a
ON a.question_id = q.id
GROUP BY qId
LIMIT 3
http://sqlfiddle.com/#!2/400994/8
上面的查询将连接表,对值进行分组,然后,然后,限制结果行的数量。如你所见,你得到所有的价值,你甚至可以计算价值,求和,连接它们......尽可能多的:
SELECT
q.id qId
, q.title qTitle
, GROUP_CONCAT( a.id SEPARATOR " ")
, SUM( a.id )
, COUNT( a.id )
FROM question q
INNER JOIN answer a
ON a.question_id = q.id
GROUP BY qId
LIMIT 3
http://sqlfiddle.com/#!2/400994/11
当然,您可能希望通过答案数量,ASC或DESC来命令它们:
SELECT
q.id qId
, q.title qTitle
, GROUP_CONCAT( a.id SEPARATOR " ")
, SUM( a.id ) sumIdsValues
, COUNT( a.id ) totalAnswers
FROM question q
INNER JOIN answer a
ON a.question_id = q.id
GROUP BY qId
ORDER BY totalAnswers ASC
LIMIT 3
http://sqlfiddle.com/#!2/400994/12
其他的是获取不同答案的值,以创建要导出的数组。在这种情况下,您可以使用CONCAT
:
SELECT
q.id qId
, q.title qTitle
, CONCAT( "[", GROUP_CONCAT( a.id SEPARATOR ", "), "]" ) idArrays
, SUM( a.id )
, COUNT( a.id )
FROM question q
INNER JOIN answer a
ON a.question_id = q.id
GROUP BY qId
LIMIT 3
http://sqlfiddle.com/#!2/400994/14
然后您将字段idArrays = [1, 2, 3, 4, 5]
作为JSON数组,您可以使用json_decode()
进行解码并分配给var。你可能会使用更复杂的结构,重要的是知道你想要复合什么,然后用CONCAT编写MySQL子句来复合它,XD