【问题标题】:Why does SELECT * FROM table INNER JOIN..ON show the intersecting column twice?为什么 SELECT * FROM table INNER JOIN..ON 两次显示相交列?
【发布时间】:2017-05-02 18:41:28
【问题描述】:

我正在使用 MySQL 将两个不同的表连接在一起。 people 和 homes。

当我尝试使用 USING 关键字将两者内部连接在一起时,它会返回一列用于我想要加入的相交列(地址):

SELECT * FROM people INNER JOIN homes USING(address);

+---------------------+------------+-----------+----------+
| address             | first_name | last_name | city     |
+---------------------+------------+-----------+----------+
| 533 Dufferin Street | Joe        | Smith     | Toronto  |
| 421 Yonge Street    | John       | Schmidt   | New York |
| 90 Bayview Avenue   | Mary       | Poppins   | Chicago  |
| 800 Keele Street    | Joe        | Dirt      | L.A      |
+---------------------+------------+-----------+----------+

然而,当您使用 ON 关键字对两个表进行内部连接时,它会返回两列 address(相交列)。

SELECT * from people INNER JOIN homes ON(people.address = homes.address);

+------------+-----------+---------------------+---------------------+----------+
| first_name | last_name | address             | address             | city     |
+------------+-----------+---------------------+---------------------+----------+
| Joe        | Smith     | 533 Dufferin Street | 533 Dufferin Street | Toronto  |
| John       | Schmidt   | 421 Yonge Street    | 421 Yonge Street    | New York |
| Mary       | Poppins   | 90 Bayview Avenue   | 90 Bayview Avenue   | Chicago  |
| Joe        | Dirt      | 800 Keele Street    | 800 Keele Street    | L.A      |
+------------+-----------+---------------------+---------------------+----------+

所以我想总结一下,为什么USING 导致列address 显示一次,而ON 导致address 显示两次?

【问题讨论】:

  • MySQL ON vs USING? 的可能重复 ...它没有深入解释为什么,但我认为这只是为了让事情变得更简单,因为无论如何 USING 都是语法糖
  • 不是重复的。这询问了 MySQL ON 与 Using 之间的一般差异。我的询问一个特定实例,说明为什么两个输出不同的结果。虽然第一个答案指出 select * FROM INNER JOIN ON 导致被列出两次,但没有解释原因。
  • 真的吗?您阅读了 Robert Rocha 的回答,但对您不满意?
  • "此外,JOIN USING 的输出抑制了冗余列:不需要打印两个匹配的列,因为它们必须具有相同的值。而 JOIN ON 生成 T1 中的所有列,然后是所有列T2 的列”
  • 唯一的事情是那是为了 Postgres。这也适用于 MySQL 吗?

标签: mysql sql


【解决方案1】:

当您使用ON people.address = home.address 时,两个表中的列名相同只是巧合——通常这种类型的ON 条件匹配具有不同名称的列。执行此操作时,不会从结果中过滤掉重复的列。

但是当您使用USING (address) 时,两个表中的列名必须相同(因为USING 不允许您关联具有不同名称的列)。由于同时拥有它们显然是多余的,因此过滤掉了重复项。

【讨论】:

    【解决方案2】:

    请参阅MySQL Join Syntax,尤其是在“加入 MySQL 5.0.12 中的处理更改”部分。 USING 或 NATURAL JOIN 将连接属性始终视为相同,因此两者之一是多余的。与以前的行为不同,从 5.0.12 开始,“冗余列被消除,列顺序根据标准 SQL 是正确的”。

    【讨论】:

      【解决方案3】:

      在这个查询中

      SELECT * from people INNER JOIN homes ON(people.address = homes.address);
      

      结果中有两个地址,即people.address和homes.address。在内部连接的情况下,两者具有相同的值。如果是另一种连接类型(外部连接或交叉连接),它们不会。

      在另一个查询中

      SELECT * FROM people INNER JOIN homes USING(address);
      

      您将两者合并到一个不合格的地址。您获得的是连接条件更易于编写(但是对于更复杂的查询,您会遇到需要限定符然后再次返回 ON 的情况)。

      USING 对于多个完全外连接特别有用*:

      select col, a.colx, b.coly, c.colz
      from a
      full outer join b using (col)
      full outer join c using (col);
      

      对

      select coalesce(a.col,b.col,c.col) as col, a.colx, b.coly, c.colz
      from a
      full outer join b on b.col = a.col
      full outer join c on c.col = coalesce(a.col,b.col);
      

      *) 但是,MySQL 不支持完全外连接。

      【讨论】:

        【解决方案4】:

        在您的控制器中 $data['address'] = $this->yourmodel->getAdd();

        尝试在你的模型中使用它。

        公共函数 getAdd() { $this->db-> select ( 'p.first_name' , 'p.last_name', a.address as add'); $this->db->join('homes a' , a.address = p.address'); $query = $this->db-> get ('people p'); $查询->返回->结果数组(); }

        【讨论】:

        • 并在你的视图上 foreach (地址作为添加):
        • 这不是这个问题的答案
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多