2010-06-05 16 views
13

Aquí es una estructura de tabla simplificada:limita los resultados de tabla unida a una fila

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 
); 

Un producto puede tener varias fotos, la primera foto del producto para cada producto (en base a la photo_order) es la foto predeterminada.

Ahora, solo necesito todas las fotos en la página de detalles del producto, pero en las páginas donde estoy enumerando varios productos, por ejemplo, una página de directorio de productos, solo quiero mostrar la foto predeterminada.

Lo que intento hacer es consultar una lista de productos que incluya la foto predeterminada para cada producto.

Obviamente, esto no funciona, devolverá todas las fotos con la información del producto duplicado para cada foto:

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 

tengo que encontrar la manera de hacer algo como esto, pero no sé la sintaxis (o si es posible)

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 

Editar: me di cuenta de una solución con la ayuda de las respuestas a continuación, gracias a todos!

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 
+0

pls proporciona un ejemplo de PRODUCT_PHOTOS - Quiero ver cómo PHOTO_ORDER controla el defecto porque usted no proporcionó tipos de datos –

+0

photo_order es sólo un número entero, que * debe * ser único por producto, pero no necesariamente garantizado – Rob

+0

Si cambia a una combinación correcta y ordena por: .product_title ASC, .photo_order ASC Creo que obtendrá una fila por producto y será la primera foto. No verá productos que no tengan una foto (que puede ser un problema). Sin embargo, debería ser una consulta mucho más simple. – TheJacobTaylor

Respuesta

6

Uso:

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 
+0

no sé si esto hace lo que está pidiendo. Especificó que se utiliza el campo photo_order, no el campo product_photo_id. –

+0

Hace exactamente lo que se necesita, solo trato de evitar las subconsultas cuando puedo, de ahí la otra respuesta. – Wrikken

+0

@Wrikken: una combinación a una tabla derivada/vista en línea no es una subconsulta. Para mí, al menos ... –

12
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 

Nota la forma en que se une a la mesa product_photos dos veces. El WHERE ph2.photo_order IS NULL arrojará todos menos el orden de foto más bajo. Sin embargo, no lo protegerá contra el duplicado de product_id/photo_orders combo, puede agregar GROUP BY en p.id si ese es el caso.

+0

¡Gracias por la respuesta! – Rob

+2

Buen trabajo. Sin sub consulta/tabla derivada. Solo necesita índices en product_id y photo_order. –

1
SELECT ... 
    .... 
GROUP BY p.product_id 
+0

Gracias por la respuesta, aunque esta solución no respetará la columna photo_order. – Rob

+0

Intente invertir el orden de clasificación. –

4
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, ph.photo_order ASC 
    GROUP BY p.product_id 
    LIMIT 0,10 
Cuestiones relacionadas