使用带有LEFT JOIN的GROUP BY或DISTINCT

时间:2015-09-25 10:48:20

标签: mysql group-by left-join

我有一个包含订单的表和一个包含用户的表。订单可以在用户表中放置一个条目。

使用以下MySQL语句,如果有匹配的用户,我会获得订单的重复值:

SELECT o.id, u.id as 'user_id', u.name
FROM orders o
LEFT JOIN users u ON o.user_id = u.id
WHERE o.status = 'active'

如果我添加GROUP BY o.id,它就可以解决问题。

SELECT o.id, u.id as 'user_id'
FROM orders o
LEFT JOIN users u ON o.user_id = u.id
WHERE o.status = 'active'
GROUP BY o.id

如果我使用SELECT DISTINCT,它也可以。

我的问题是:

  1. 为什么会返回重复的字段?
  2. 使用GROUP BY或SELECT DISTINCT更正确吗?

3 个答案:

答案 0 :(得分:1)

您的详细信息查询 - 返回每一行的查询,而不是使用DISTINCT或GROUP BY的重复数据删除版本 - 在users中找到的行与orders中的每一行匹配1}}。所以,它尽职尽责地返回所有这些行。

要正确解决您的问题,您需要找出每个订单有多个users行的原因。也就是说,对于order.user_id的某些值,有users.id的多个值。

这对我来说有点奇怪,但我不了解你的数据模型。您可能需要调查此数据异常。传统模式将使每个用户能够下达多个订单,但每个订单仅与一个用户相关。在该模式中,此查询将为每个订单生成一行,但仍包括没有订单的用户:

SELECT u.id AS user_id, o.id AS order_id
  FROM users AS u
  LEFT JOIN orders AS o ON o.user_id = u.id

这可能是你想要的吗?

与某些人相反。相信,GROUP BY orders.idSELECT DISTINCT orders.id, users.id 是同一件事。实际上,您建议使用GROUP BY误用notorious MySQL extension to GROUP BY.标准SQL会拒绝您的GROUP BY。它只接受GROUP BY orders.id, users.id,这确实等同于DISTINCT。

答案 1 :(得分:0)

  

为什么会返回重复字段?

它返回重复项,因为你没有应用任何东西来阻止它这样做。当您应用GROUP BY或DISTINCT时,您实际上会停止重复。

  

使用GROUP BY或SELECT DISTINCT

是否更正确

两者都是等效的,可以根据您的方便使用。您可能会发现,在您的表上未创建索引的情况下,DISTINCT比GROUP BY更快。但这并没有使GROUP BY的使用不正确。如果创建了索引,那么它们彼此都是等价的。

答案 2 :(得分:0)

您的查询根本不需要JOIN。你可以使用:

SELECT o.id, o.user_id
FROM orders o
WHERE o.status = 'active';

至于SELECT DISTINCTGROUP BY。两者在性能上应相当(或非常接近)。他们的工作基本相同。

GROUP BY的优点是可以添加聚合函数。 DISTINCT的优势在于您不必两次列出所有列,并且接受*