限制在INNER JOINS中不起作用

时间:2014-05-29 10:11:15

标签: mysql join limit inner-join

我确定已经问过这个问题,但我不禁想知道为什么其中一个INNER JOINS中的“LIMIT 3”只返回“ON子句”中指定avp.productID的单个imgUrl ! LIMIT在INNER JOIN中不起作用吗?我可以用什么更好的方法来达到这个目的?

$query = "SELECT
p.productID,
p.productDesc,
p.productQty,
p.productPr,
p.type,
p.gender,
p.date

From
products AS p
INNER JOIN(
    Select 
        c.productID, 
        GROUP_CONCAT(DISTINCT c.availCol) AS color_list 
    FROM
        availColors AS c GROUP BY c.productID) AS colors
        ON
            p.productID = colors.productID
    INNER JOIN(
        SELECT
            s.productID,
            GROUP_CONCAT(s.availSizes) AS size_list
        FROM
            availSizes AS s
        GROUP BY
            s.productID
    ) AS sizes
ON
    p.productID = sizes.productID
INNER JOIN(
        SELECT
            avp.productID,
            avp.productImg
        FROM
            availImg AS avp
        ORDER BY
            avp.productID
        LIMIT 3) AS images
ON
    images.productID =  p.productID
WHERE
    p.productID = ?
GROUP BY
    p.productID";

1 个答案:

答案 0 :(得分:0)

您当前的查询有一个子查询,返回3个图像,按产品ID排序。此子查询不会检查图像是否属于您要搜索的产品,因此可以轻松地为不同的产品带回3张图像。这将导致主查询尝试基于产品ID对子查询进行内部联接并找不到匹配的记录。

由于您的其他2个子查询仅为每个产品ID返回一行(由于GROUP_CONCAT)并且您似乎只想一次检查一个产品ID,我认为您可以通过执行以下操作来解决此问题正常连接到图像表(没有子查询)并对主查询设置限制。

像这样: -

$query = "SELECT
        p.productID,
        p.productDesc,
        p.productQty,
        p.productPr,
        p.type,
        p.gender,
        p.date
From products AS p
INNER JOIN
(
    Select c.productID, 
            GROUP_CONCAT(DISTINCT c.availCol) AS color_list 
    FROM availColors AS c 
    GROUP BY c.productID
) AS colors
ON p.productID = colors.productID
INNER JOIN
(
    SELECT s.productID,
            GROUP_CONCAT(s.availSizes) AS size_list
    FROM availSizes AS s
    GROUP BY s.productID
) AS sizes
ON p.productID = sizes.productID
INNER JOIN availImg images
ON images.productID =  p.productID
WHERE p.productID = ?
ORDER BY images.productID, images.productImg
LIMIT 3";

但是,如果您想要带回多个产品ID,那么它会变得有点复杂。一种解决方案是使用生成的序列号为每个产品带回图像,然后检查连接的ON子句,它是产品的前3个图像之一: -

$query = "SELECT
        p.productID,
        p.productDesc,
        p.productQty,
        p.productPr,
        p.type,
        p.gender,
        p.date
From products AS p
INNER JOIN
(
    Select c.productID, 
            GROUP_CONCAT(DISTINCT c.availCol) AS color_list 
    FROM availColors AS c 
    GROUP BY c.productID
) AS colors
ON p.productID = colors.productID
INNER JOIN
(
    SELECT s.productID,
            GROUP_CONCAT(s.availSizes) AS size_list
    FROM availSizes AS s
    GROUP BY s.productID
) AS sizes
ON p.productID = sizes.productID
INNER JOIN
(
    SELECT avp.productID,
        avp.productImg,
        @seq:=IF(@prev_productID = avp.productID, @seq + 1, 1) AS seq,
        @prev_productID := avp.productID
    FROM availImg AS avp
    CROSS JOIN (SELECT @prev_productID:=0, @seq:=0) sub1
    ORDER BY avp.productID
) AS images
ON images.productID =  p.productID
AND images.seq <= 3
WHERE p.productID = ?";

另一种可能的方法是使用GROUP_CONCAT为每个产品获取逗号分隔的图像ID列表,使用SUBSTRING_INDEX获取前3个,然后使用FIND_IN_SET将其连接到images表以获取图像的其余部分细节: -

$query = "SELECT
        p.productID,
        p.productDesc,
        p.productQty,
        p.productPr,
        p.type,
        p.gender,
        p.date
From products AS p
INNER JOIN
(
    Select c.productID, 
            GROUP_CONCAT(DISTINCT c.availCol) AS color_list 
    FROM availColors AS c 
    GROUP BY c.productID
) AS colors
ON p.productID = colors.productID
INNER JOIN
(
    SELECT s.productID,
            GROUP_CONCAT(s.availSizes) AS size_list
    FROM availSizes AS s
    GROUP BY s.productID
) AS sizes
ON p.productID = sizes.productID
INNER JOIN
(
    SELECT avp.productID,
        SUBSTRING_INDEX(GROUP_CONCAT(avp.productImg), ',', 2), AS three_images_per_product
    FROM availImg AS avp
    GROUP BY avp.productID
) AS images
ON images.productID =  p.productID
INNER JOIN availImg
ON availImg.productID =  images.productID
AND FIND_IN_SET(availImg.productImg, images.three_images_per_product)
WHERE p.productID = ?";

请注意,您的原始查询实际上没有SELECT子句中的任何图像详细信息,并且您已经完成了GROUP BY p.productID,这意味着即使找到3个图像,查询也只会返回每个产品一行id无论如何。