【问题标题】:Join three table codeigniter 4加入三表codeigniter 4
【发布时间】:2020-11-03 22:41:25
【问题描述】:

大家好,我是 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();

还有其他方法可以加入他们吗? 谢谢

【问题讨论】:

  • 您似乎错过了选择数据,您是否阅读过此codeigniter.com/user_guide/database/…? $this->select(),只构建查询的SELECT子句
  • @Vickel 当我更改为 $this->select('*');加入后,我没有结果。但是当我删除连接线上的 table_1 时,我得到了结果,但只是针对 table_2。
  • 如果您使用的是 MySQL,您将如何使用普通 SQL 来执行此操作?

标签: mysql codeigniter codeigniter-4


【解决方案1】:

您当前所拥有的将无法使用,因为您的 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"
  }
}

请注意,您的查询中出现了两次 name。那么哪一个会赢呢?似乎只使用了 Table_2.name,对 Table_1.name 的任何引用都是 NULL,因为它没有被使用。

您可以使用别名为它们赋予不同的名称,但是您会得到类似 name_1 和 name_2 的名称,那么它是哪一个?这是由于您的 Table_1 和 Table_2 中的重复,并且您要求两者。

更好的方法 因此,在这种情况下,您需要对 Table_1 和 Table_2 执行 UNION。

我认为 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();
}

因此,在此示例中,我们在 Select.xml 中指定了您需要的 3 个字段。注意 T12.name 被重命名为作者。 (见下面的输出)

然后必须在 Table_1 和 Table_2 上执行UNION,并将结果命名(别名)为 T12(Table_1 和 Table_2 的简写),因为结果需要一个新名称。

然后对 Table_3 执行LEFT JOIN,这将给出所有存在 NULL 的组合,因此 WHERE 语句使用 Table_3.author 上的“IS NOT NULL”过滤掉这些组合。

我省略了ORDER BY,因为它并不是真正需要的,如果您愿意,可以重新添加。

结果的 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"
  }
}

因此,这将为您提供每个匹配行的 ID、作者和标题,正如您使用示例表所请求的那样。

【讨论】:

    猜你喜欢
    • 2018-03-14
    • 1970-01-01
    • 2014-02-24
    • 2016-02-04
    • 2015-04-08
    • 2014-08-31
    • 1970-01-01
    • 2011-07-20
    • 2019-09-13
    相关资源
    最近更新 更多