将连接表的结果限制为一行

Rob*_*Rob 19 mysql sql

这是一个简化的表结构:

TABLE products (
 product_id INT (primary key, auto_increment),
 category_id INT,
 product_title VARCHAR,
 etc
);

TABLE product_photos (
 product_photo_id (primary key, auto_increment),
 product_id INT,
 photo_href VARCHAR,
 photo_order INT
);
Run Code Online (Sandbox Code Playgroud)

一个产品可以有多张照片,每张产品的第一张产品照片(基于photo_order)是默认照片.

现在,我只需要产品详细信息页面上的所有照片,但在我列出多个产品的页面上,例如产品目录页面,我只想显示默认照片.

所以我要做的是查询产品列表,包括每个产品的默认照片.

这显然不起作用,它将返回所有照片与每张照片的产品信息重复:

SELECT p.*, ph.*
FROM products AS p
LEFT JOIN product_photos AS ph
ON p.product_id=ph.product_id
ORDER BY p.product_title ASC
Run Code Online (Sandbox Code Playgroud)

我需要弄清楚如何做这样的事情,但我不知道语法(或者是否可能)

SELECT p.*, ph.*
FROM products AS p
LEFT JOIN product_photos AS ph
    ON p.product_id=ph.product_id  **ORDER BY ph.photo_order ASC LIMIT 1**
ORDER BY p.product_title ASC
Run Code Online (Sandbox Code Playgroud)

编辑:我在下面的答案帮助下找到了解决方案,谢谢大家!

SELECT p.*, ph.*
FROM products AS p
LEFT JOIN product_photos AS ph 
    ON p.product_id=ph.product_id
    AND ph.photo_order =
    (
        SELECT MIN(z.photo_order)
        FROM product_photos AS z
        WHERE z.product_id=p.product_id
    )
GROUP BY p.product_id
ORDER BY p.product_title ASC
Run Code Online (Sandbox Code Playgroud)

Wri*_*ken 14

SELECT p.*, ph.*
FROM products AS p
INNER JOIN product_photos AS ph
    ON p.product_id = ph.product_id
LEFT JOIN product_photos AS ph2
    ON p.product_id = ph2.product_id
    AND ph2.photo_order < ph.photo_order
WHERE ph2.photo_order IS NULL
ORDER BY p.product_title ASC
Run Code Online (Sandbox Code Playgroud)

请注意它如何连接到product_photos表两次.WHERE ph2.photo_order IS NULL除了最低的照片顺序之外,它将丢弃所有照片.它不会保护您免受重复的product_id/photo_orders组合,但GROUP BY如果是这种情况,您可以在p.id上添加一个.

  • 不错的工作.没有子查询/派生表.只需要在product_id和photo_order上使用索引. (2认同)

OMG*_*ies 10

使用:

SELECT p.*,
       pp.*
  FROM PRODUCTS p
  JOIN PRODUCT_PHOTOS pp ON pp.product_id = p.product_id
  JOIN (SELECT x.product_id,
               MIN(x.photo_order) AS default_photo
          FROM PRODUCT_PHOTOS x
      GROUP BY x.product_id) y ON y.product_id = pp.product_id
                              AND y.default_photo  = pp.photo_order
Run Code Online (Sandbox Code Playgroud)

  • 哦,没有进入那个。不完全是火焰战争诱饵,但是派生表是否是子查询是非常有争议的,我现在不会开始。这不是批评,我对子查询和/或派生表的不使用有时是不合逻辑的。 (3认同)