简体   繁体   English

在 codeigniter 中连接来自多个表的数据

[英]Concatenate data from multiple tables in codeigniter

How do you guys get the data from two or more tables and manipulate it in codeigniter?你们如何从两个或多个表中获取数据并在 codeigniter 中对其进行操作?

Let's assume that we have 2 tables questions and answers.假设我们有 2 个表格问题和答案。 A question can have one or more answer.一个问题可以有一个或多个答案。 Now let's assume that an answer can have likes and unlikes.现在让我们假设一个答案可以有喜欢和不喜欢。 How do you people get all the questions with answers for display them in a view?.人们如何获得所有问题及其答案以在视图中显示它们?。 I will show you my solution but I'm curious about yours.我会告诉你我的解决方案,但我对你的很好奇。

I make use of libraries like so:我像这样使用库:

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

Now in the answerslibrary i can take the same aproach to get the answers and answerlikes and unlikes.现在,在答案库中,我可以采用相同的方法来获得答案以及喜欢和不喜欢的答案。

A draw back in my aproach is that if I want to display my questions with pagination sorted by number of answers or likes/unlikes etc i have to use join or nested queries inside my model and i canot make use of the power of my libraries.我的方法的一个缺点是,如果我想用按答案数量或喜欢/不喜欢等排序的分页显示我的问题,我必须在我的模型中使用连接或嵌套查询,我不能利用我的库的力量。

How do you manage this task ?你如何管理这个任务?

As @nevermind points out, the only way is by JOIN in your SQL.正如@nevermind 指出的那样,唯一的方法是在您的 SQL 中JOIN Any PHP loop of data as you do is just going to be a bottleneck, in both PHP and MySQL.在 PHP 和 MySQL 中,您所做的任何 PHP 数据循环都将成为瓶颈。 With an only query with a JOIN you'll get all the results, (use the GROUP BY clause with SUM and COUNT to get the number of the elements) and you'll be able of use ORDER BY .使用带有JOIN的唯一查询,您将获得所有结果(将GROUP BY子句与SUMCOUNT以获取元素数),并且您将能够使用ORDER BY And you only use a query against the DDBB, while with your method you use a lot of queries (1 per row) to get the same result.您只对 DDBB 使用查询,而使用您的方法,您使用大量查询(每行 1 个)来获得相同的结果。 Believe me, I've seen code in system as which you proposed above, and it's like a straitjacket.相信我,我已经在系统中看到过你上面提出的代码,它就像一件紧身衣。

If you wanted more help about using the MySQL clauses, post your code and I'll point you about how to do it.如果您需要有关使用 MySQL 子句的更多帮助,请发布您的代码,我将指导您如何操作。

UPDATE更新

Lets try a bit with SQLFiddle:让我们尝试一下 SQLFiddle:

Starting point: Two tables, question and answer, with the following structure:起点:两张表,一问一答,结构如下:

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 http://sqlfiddle.com/#!2/400994/6

As you see, in the fiddle we get the INNER JOIN with the proper data, as many rows as the JOIN of both table.如您所见,在小提琴中,我们获得了具有正确数据的INNER JOIN ,行数与两个表的 JOIN 一样多。

With a GROUP BY and a LIMIT , we can get all the values, with no worries:使用GROUP BYLIMIT ,我们可以获得所有值,而无需担心:

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 http://sqlfiddle.com/#!2/400994/8

The query above will join the tables, group the values, and then, and only then, limit the number of the resultant rows.上面的查询将连接表,对值进行分组,然后限制结果行的数量。 As you see, you get all the values, and you can even count the values, sum them, concatenate them... As much as you want:如您所见,您获得了所有值,您甚至可以对这些值进行计数、求和、连接... 随心所欲:

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 http://sqlfiddle.com/#!2/400994/11

And of course, you may wish order them by number of answers, ASC or DESC:当然,您可能希望按答案数量、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 http://sqlfiddle.com/#!2/400994/12

Other thing is getting the values of the different answers, to create an array to export.另一件事是获取不同答案的值,以创建要导出的数组。 In that case, you may compound a JSON from the values with CONCAT :在这种情况下,您可以使用CONCAT从值中合成一个 JSON:

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 http://sqlfiddle.com/#!2/400994/14

And you get the field idArrays = [1, 2, 3, 4, 5] as a JSON array you may decode with json_decode() and assign to a var.你得到字段idArrays = [1, 2, 3, 4, 5]作为一个 JSON 数组,你可以用json_decode()解码并分配给一个 var。 You may use even more complicated structure, the important thing is knowing what you want to compound, and then write the MySQL clause with CONCAT to compound it, XD你可以用更复杂的结构,重要的是知道你要复合什么,然后用CONCAT写MySQL子句来复合它,XD

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM