在连接表上使用LIMIT 1连接MySQL

Joh*_*son 59 mysql join limit

我想加入两个表,但只能获得table1上每条记录的table2记录

例如:

SELECT c.id, c.title, p.id AS product_id, p.title
FROM categories AS c
JOIN products AS p ON c.id = p.category_id
Run Code Online (Sandbox Code Playgroud)

这会让我记录下来products,这不是我想要的.我想要每个类别1个[第一个]产品(我sort在产品领域有一个专栏).

我该怎么做呢?

Kos*_*nos 66

我喜欢在类似问题中描述的更多另一种方法:https://stackoverflow.com/a/11885521/2215679

这种方法更好,尤其是在需要在SELECT中显示多个字段的情况下.Error Code: 1241. Operand should contain 1 column(s)为每列避免或双重子选择.

对于您的情况,Query应如下所示:

SELECT
 c.id,
 c.title,
 p.id AS product_id,
 p.title AS product_title
FROM categories AS c
JOIN products AS p ON
 p.id = (                                 --- the PRIMARY KEY
  SELECT p1.id FROM products AS p1
  WHERE c.id=p1.category_id
  ORDER BY p1.id LIMIT 1
 )
Run Code Online (Sandbox Code Playgroud)

  • 与标准连接相比,性能影响是什么? (6认同)
  • 不幸的是,太慢了:( (2认同)

Gra*_*avy 22

@ goggin13的接受的答案看起来不对.到目前为止提供的其他解决方案将起作用,但是受到n + 1问题的困扰,因此遭受性能损失.

n + 1问题:如果有100个类别,那么我们必须做1个选择来获取类别,然后对于返回的100个类别中的每个类别,我们需要选择以获得该类别中的产品.因此将执行101个SELECT查询.

我的替代解决方案解决了n + 1问题,因此应该显着提高性能,因为只执行了2次选择.

SELECT
  *
FROM
    (SELECT c.id, c.title, p.id AS product_id, p.title
    FROM categories AS c
    JOIN products AS p ON c.id = p.category_id
    ORDER BY c.id ASC) AS a 
GROUP BY id;
Run Code Online (Sandbox Code Playgroud)

  • 有趣。通常,如果在单个查询中使用ORDER BY和GROUP BY,则GROUP BY将首先运行,而ORDER BY将对组进行排序。我认为这是使ORDER BY首先执行的方法。 (2认同)
  • @ChrisBartley-只需在任何聚合列上的字段中添加缺少的分组。您还可以按照https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html使用`ANY_VALUE()` (2认同)

Jes*_*nck 10

SELECT c.id, c.title, p.id AS product_id, p.title
FROM categories AS c
JOIN products AS p ON c.id = p.category_id
GROUP BY c.id
Run Code Online (Sandbox Code Playgroud)

这将返回产品中的第一个数据(等于限制1)

  • 这将返回一个,但这一定是第一个吗? (2认同)

Kra*_*rab 5

那这个呢?

SELECT c.id, c.title, (SELECT id from products AS p 
                            WHERE c.id = p.category_id 
                            ORDER BY ... 
                            LIMIT 1)
   FROM categories AS c;
Run Code Online (Sandbox Code Playgroud)


gog*_*n13 -43

我会尝试这样的事情:

SELECT C.*,
      (SELECT P.id, P.title 
       FROM products as P
       WHERE P.category_id = C.id
       LIMIT 1)
FROM categories C
Run Code Online (Sandbox Code Playgroud)

  • 这会引发错误,错误代码:1241。操作数应包含 1 列 (21认同)