将 GROUP BY 或 DISTINCT 与 LEFT JOIN 结合使用

Using GROUP BY or DISTINCT with a LEFT JOIN

我有一个 table 订单和一个 table 用户。可以使用用户 table.

中的条目下订单

使用以下 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. 为什么 return 字段重复?
  2. 使用 GROUP BY 还是 SELECT DISTINCT 更正确?

Why does it return duplicate fields?

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

Is it more correct to use GROUP BY or SELECT DISTINCT

两者是等效的,可以根据您的方便使用。您可能会发现 DISTINCT 比 GROUP BY 更快,因为索引不是在您的 table 上创建的。但这并不会使 GROUP BY 的用法不正确。如果创建了索引,那么它们是等价的。

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

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

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

GROUP BY的优点是可以添加聚合函数。 DISTINCT 的优点是你不必列出所有列两次,它接受 *.

您的 detail 查询 -- 返回每一行的查询,而不是使用 DISTINCT 或 GROUP BY 的去重版本 -- 在 users 匹配项中发现不止行orders 中的每一行。因此,它尽职尽责地返回所有这些行。

要正确解决您的问题,您需要弄清楚为什么每个订单有多个 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。