【问题标题】:Limit not working in INNER JOINS限制在 INNER JOINS 中不起作用
【发布时间】:2014-05-29 10:11:15
【问题描述】:

我确定这个问题已经被问过了,但我不禁想知道为什么一个 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";

【问题讨论】:

  • 您的受限内部连接查询未指定产品 ID。它将返回第一个产品 ID 的最后 3 张图像。如果产品 id 1 有 3 张图片,产品 id 2 有 3 张图片,则无论您搜索的是产品 id 1 还是产品 2,该查询都会返回产品 id 1 的 3 张图片(这将导致 ON 条件失败)。

标签: mysql join limit inner-join


【解决方案1】:

您当前的查询有一个子查询,它返回 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 将其与图像表连接以获取图像的其余部分详情:-

$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 的一行.

【讨论】:

    猜你喜欢
    • 2022-09-28
    • 2021-09-01
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多