【问题标题】:What is the behaviour of a join on columns not in both tables?不在两个表中的列上的连接行为是什么?
【发布时间】:2015-02-28 07:10:00
【问题描述】:
table: users
columns: id

table: products
columns: id

table: product_images
columns: product_id |  path

table: cart
columns: user_id | product_id 

底部 2 个表中的 product_id 对应于 products 表中的 id。 cart 表中的 user_id 对应于 users 表中的 id。

我和我的朋友正在开发一个通用的购物网站,只是为了好玩。

要求:给定一个user_id,遍历用户的购物车并返回products表中所有对应的行,并且该产品恰好有1张图片(可能有多张图片)。

这是我们的查询(似乎有效):

SELECT products.*, product_images.path
FROM products
INNER JOIN cart 
ON cart.product_id = products.id AND cart.user_id = 13  /* arbitrary id */
LEFT OUTER JOIN product_images 
ON product_images.product_id = cart.product_id
GROUP BY cart.product_id

第一个连接对我来说很直观,因为连接中涉及的两个表都在每个表中的列上连接。

这是我感到困惑的第二次加入。
我的理解是第一次连接会产生一个虚拟表。 然后将该虚拟表与 product_images 表连接,但令人困惑的部分是 ON 条件没有使用直接属于虚拟表的列。

那么这里到底发生了什么?

请注意,我知道如何以对我来说更直观的方式重写查询,并且理解对我来说很重要的概念。

起初我认为这并不常见,但我注意到 w3schools 在此链接底部做了同样的事情:http://www.w3schools.com/sql/sql_groupby.asp

【问题讨论】:

  • 您是否想要所有只有 1 张图片且在购物车中的产品?

标签: mysql join group-by left-join


【解决方案1】:

cartproducts 是内连接的。

进入下一个连接的虚拟表包括来自cart的所有列和来自products的所有列

这个虚拟/逻辑表如下。

SELECT products.id,
       cart.user_id,
       cart.product_id
FROM   products
       INNER JOIN cart
         ON cart.product_id = products.id
            AND cart.user_id = 13;

所以这个虚拟表中有三列。 products.id,cart.user_id,cart.product_id

然后使用来自虚拟表的product_imagescart.product_id 中的列将这个虚拟表左连接到product_images

【讨论】:

  • @KacyRaye - 参与该联接的左表是products * carts,因此它将产品和购物车中的所有列都纳入范围。所涉及的右表是product_images,以便将product_images 的列带入范围。所以左连接谓词可以引用这三个表中的任何一个列。
  • @KacyRaye 你的问题是“令人困惑的部分是 ON 条件没有使用直接属于虚拟表的列。”所以行在这里根本不相关。如果您对一般结果感到困惑,请参阅my answer here。左外连接的解释完全一样,只是左边的表不是基表,而是我回答中查询的结果。
  • @KacyRaye - 是的,它使用的是虚拟表中的 product_id 列(当然,它最初源自 cart)。
  • @KacyRaye - 我认为我的回答在这一点上可能更清楚。希望是现在!
  • @KacyRaye - 逻辑上 GROUP BY 发生在连接和 where 子句(如果存在)之后。所以它将使用第二个连接产生的虚拟表中的cart.product_id 列。 SELECT 在逻辑上几乎在最后运行。之后发生的唯一步骤是ORDER BYLIMIT
猜你喜欢
  • 2014-12-17
  • 2019-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-30
  • 2018-05-11
相关资源
最近更新 更多