【问题标题】:Third join on NULL doesn't return values (Codeigniter)NULL 上的第三个连接不返回值(Codeigniter)
【发布时间】:2017-06-23 11:46:42
【问题描述】:

我有一个不返回所需值的连接语句。

原因是第三个表 (cvi) 在许多情况下不会包含与第四个表 (cmi) 匹配的任何行。如果未连接任何值,则结果不会显示表 ccv 中的所需值。

    /* Tables */
    $this->db->from($this->table_c.' c');
    $this->db->join($this->table_cv.' cv', 'cv.content_id = c.id', 'inner');
    $this->db->join($this->table_cvi.' cvi', 'cvi.version_id = cv.id AND cvi.meta_key = "M"');
    $this->db->join($this->table_cmi.' cmi', 'cmi.id = cvi.meta_value');

我尝试了外连接,但由于表 cvi 位于表 cvcmi 之间,因此这两个表中没有公共值。

+------------+
|        c   |
|            |
|      +-----|------+
|      |     |  cv  |
+------------+      | 
       |       +------------+
       |       |    |  cvi  | When this table is empty, the result is empty
       +-------|----+       | I want it to still show result of c and cv
               |      +------------+
               |      |     |  cmi |
               +------------+      |
                      |            |
                      |            |
                      +------------+

这里说明了为什么没有共享价值观。 因此,我正在寻找一种方法来创建一个仅在 cvi 包含值时才加入 cmi 的条件。否则只在cvi 上进行外连接,并且不包括表cmi

您能提供一些想法或解决方案吗?

编辑 为了清楚起见,以下是表格:

/* Table c */
+------+--------+
| id   | title  |
+------+--------+

/* Table cv */
+------+----------+
| id   | version  |
+------+----------+

/* Table cvi */
+------+------------+-----------+------------+
| id   | version_id | meta_key  | meta_value |
+------+------------+-----------+------------+
/* when meta_key is 'M' then the meta_value will contain the cmi.id which is used for the join (regard it as meta_id) */
/* When this table is empty there won't be data in `cmi` either. When it's empty the join removes the data result that should be present from table `c`. */

/* Table cmi */
+------+-----------+------------+
| id   | item_key  | item_value |
+------+-----------+------------+

这是cvcmi 表中有数据时的结果。

Array (
        [0] => stdClass Object
            (
                [id] => 5 /* This is c.id */
                [title] => Content title
                [version_id] => 8 /* This is cv.id */
                [version] => 0
                [meta_key] => M
                [meta_value] => 23 /* (This is the id of the item below, cmi.id) */
                [item_key] => KEY1
                [item_value] => Value
            )
)

【问题讨论】:

  • 您能展示数据示例并解释您期望的结果集吗?目前你只有inner join所以你不能得到任何结果(看看你的插图)。
  • c 中有对应的行时,我希望表c 中的每行至少有一个结果(此连接是图中未显示的连接)。所以ccv 之间存在内部连接。如果所有表中只有可用值,则此内部连接是正确的并产生正确的结果。但是如果第三个表cvi 中没有值,那么到第四个表cmi 的链接是“损坏的”,它会从ccv 表的内部连接中删除值。即使cvicmi 表中没有要连接的值,这些也需要保留在结果中。

标签: php mysql codeigniter join


【解决方案1】:

我认为你必须采取left joins

/* Tables */
$this->db->from($this->table_c.' c');
$this->db->join($this->table_cv.' cv', 'cv.content_id = c.id', 'inner');
$this->db->join($this->table_cvi.' cvi', 'cvi.version_id = cv.id AND cvi.meta_key = "M"', 'left');
$this->db->join($this->table_cmi.' cmi', 'cmi.id = cvi.meta_value', 'left');

因此,如果 cvi 和 cmi 的连接条件未创建任何结果,您将获得空列。

在您发表评论后编辑:也许EXISTS 有帮助:

$this->db->where("EXISTS(SELECT * FROM cmi)");

Codeigniter subquery exists

【讨论】:

  • 问题是(在我看来)不是外连接、内连接、左连接还是右连接,因为当链接表中没有任何内容时,这些值将永远不可连接 cvi .我需要找到一个解决方案来测试cvi 表的结果,并且只有在cvi 中有任何结果时才加入cmi。像一些条件。
  • 我试过这个,但到目前为止没有成功。你能详细解释一下这将如何解决它。只是因为我不确定我是否理解子查询将如何知道在给定其余查询的情况下要选择哪些数据。谢谢。
  • 也许我不明白你的问题。即使没有与 cvi 匹配的行,您是否想显示来自 cmi 的数据?如果您可以为所有 4 个表和 1 个您期望的结果显示一些示例数据,这会更容易。因为使用左连接,即使 cvi 或 cmi 上没有匹配的键,也会显示来自 c 和 cv 的数据。
  • 不,我想显示来自ccv 的数据,即使cvicmi 中没有数据。这在我当前的联接中不会发生,因为cvi 中的缺失数据充当了cvcmi 之间的链接。我已将表格和结果添加到问题中,因此您有机会看到它们。谢谢。注意:如果我删除最后一个连接(到表cmi),那么你是对的,左连接是答案,但不是在那里。我相信我需要使那个加入有条件,所以它只发生在cvi 有内容时。
猜你喜欢
  • 1970-01-01
  • 2012-10-11
  • 2019-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
相关资源
最近更新 更多