Присоединяйтесь к трем таблицам codeigniter 4 - PullRequest
0 голосов
/ 14 июля 2020

Привет всем, я новичок в codeigniter 4 и в настоящее время работаю над небольшим проектом в проекте. Я пытаюсь объединить три таблицы и отобразить данные в одной таблице.

Table_1
id unique_id Name
1  1111      Sam   
2  2222      Charlote

Table_2
id unique_id Name
1  1212      Jhon 
2  5151      Alex

Table_3
id author title
1  1111   Book_1
2  5151   Book_2
3  1111   Book_3


Result
------------------------
| No | Author | Title  |
------------------------
| 1  | Sam    | Book_1 |
| 2  | Alex   | Book_2 |
| 3  | Sam    | Book_3 |
------------------------

Я пытался присоединиться, но не работает.

        $this->join('Table_1', 'Table_1.unique_id = Table_3.author ');
        $this->join('Table_2', 'Table_2.unique_id = Table_3.author ');
        $this->select('Table_1.Name');
        $this->select('Table_2.Name');
        $this->select('Table_3.*');
        $this->orderBy('Table_3.id');
        return  $this->findAll();

Есть ли другой способ присоединиться к ним? Спасибо

1 Ответ

0 голосов
/ 14 июля 2020

То, что у вас сейчас есть, не будет работать, потому что ваши Table_1 и Table_2 фактически являются одной и той же таблицей.

Взяв вашу Попытку и исправив ее, чтобы использовать LEFT JOIN

public function example_1() {
    $this->join('Table_1', 'Table_1.unique_id = Table_3.author', 'LEFT');
    $this->join('Table_2', 'Table_2.unique_id = Table_3.author', 'LEFT');
    $this->select('Table_1.Name');
    $this->select('Table_2.Name');
    $this->select('Table_3.*');
    $this->orderBy('Table_3.id');
    $result = $this->findAll();

    echo $this->db->getLastQuery();

    return $result;
}

Вы получите ...

SELECT `Table_1`.`Name`, `Table_2`.`Name`, `Table_3`.*
FROM `Table_3`
LEFT JOIN `Table_1` ON `Table_1`.`unique_id` = `Table_3`.`author`
LEFT JOIN `Table_2` ON `Table_2`.`unique_id` = `Table_3`.`author`
ORDER BY `Table_3`.`id`

array(3) {
  [0]=>
  array(4) {
    ["Name"]=>
    NULL
    ["id"]=>
    string(1) "1"
    ["author"]=>
    string(4) "1111"
    ["title"]=>
    string(6) "Book_1"
  }
  [1]=>
  array(4) {
    ["Name"]=>
    string(4) "Alex"
    ["id"]=>
    string(1) "2"
    ["author"]=>
    string(4) "5151"
    ["title"]=>
    string(6) "Book_2"
  }
  [2]=>
  array(4) {
    ["Name"]=>
    NULL
    ["id"]=>
    string(1) "3"
    ["author"]=>
    string(4) "1111"
    ["title"]=>
    string(6) "Book_3"
  }
}

Обратите внимание, что у вас есть два вхождения имени в вашем запросе. Так кто же победит? Похоже, что используется только Table_2.name, а любая ссылка на Table_1.name имеет значение NULL, поскольку оно не используется.

Вы можете дать им разные имена, используя псевдонимы, но тогда у вас будет что-то вроде name_1 и name_2, так какой из них это? Это связано с дублированием в таблицах Table_1 и Table_2, и вы запрашиваете оба.

Лучший способ Таким образом, в этом случае вам нужно будет выполнить UNION для Table_1 и Table_2.

Я не думаю, что в построителе запросов CI есть команда UNION.

Используя mysql, это будет ...

public function get_book_and_author() {
    $sql = "SELECT Table_3.id, T12.name as author, Table_3.title 
            FROM (
                SELECT Table_1.* FROM Table_1
            UNION
                SELECT Table_2.* FROM Table_2
                ) as T12
            LEFT JOIN Table_3 ON T12.unique_id = Table_3.author  
            WHERE Table_3.author IS NOT NULL
            ";
    $result = $this->db->query($sql);

    return $result->getResultArray();
}

Итак, в этом Например, мы указали 3 поля, которые вам нужны в Select. Обратите внимание, что имя T12.name переименовано в author. (См. Вывод ниже)

Затем необходимо выполнить UNION для Table_1 и Table_2, и результат будет назван (с псевдонимом) как T12 (сокращение для Table_1 и Table_2), поскольку результат требует нового имени.

Затем LEFT JOIN выполняется для Table_3, что даст все комбинации, в которых будут NULLS, поэтому оператор WHERE отфильтровывает их, используя «IS NOT NULL» в Table_3author.

Я пропустил ORDER BY, поскольку он на самом деле не нужен, и вы можете добавить его обратно, если вы sh к.

Результат var_dump () дает ...

array(3) {
  [0]=>
  array(3) {
    ["id"]=>
    string(1) "1"
    ["author"]=>
    string(3) "Sam"
    ["title"]=>
    string(6) "Book_1"
  }
  [1]=>
  array(3) {
    ["id"]=>
    string(1) "2"
    ["author"]=>
    string(4) "Alex"
    ["title"]=>
    string(6) "Book_2"
  }
  [2]=>
  array(3) {
    ["id"]=>
    string(1) "3"
    ["author"]=>
    string(3) "Sam"
    ["title"]=>
    string(6) "Book_3"
  }
}

Таким образом, вы получите идентификатор, автора и заголовок для каждой совпадающей строки, как вы запросили, используя примеры таблиц.

...