MySQL LIMIT в коррелированном подзапросе - PullRequest
1 голос
/ 20 августа 2010

У меня есть коррелированный подзапрос, который вернет список количеств, но мне нужно самое большое количество, и только самое высокое.Поэтому я попытался ввести порядок и LIMIT, равный 1, чтобы достичь этого, но MySQL выдает ошибку, утверждая, что он еще не поддерживает ограничения в подзапросах.Есть мысли о том, как обойти это?

SELECT Product.Name, ProductOption.Name, a.Qty, a.Price, SheetSize.UpgradeCost,
        FinishType.Name, FinishOption.Name, FinishTierPrice.Qty, FinishTierPrice.Price
FROM `Product`
    JOIN `ProductOption`
        ON Product.idProduct = ProductOption.Product_idProduct
    JOIN `ProductOptionTier` AS a
        ON a.ProductOption_idProductOption = ProductOption.idProductOption
    JOIN `PaperSize`
        ON PaperSize.idPaperSize = ProductOption.PaperSize_idPaperSize
    JOIN `SheetSize`
        ON SheetSize.PaperSize_idPaperSize = PaperSize.idPaperSize
    JOIN `FinishOption`
        ON FinishOption.Product_idProduct = Product.idProduct
    JOIN `FinishType`
        ON FinishType.idFinishType = FinishOption.Finishtype_idFinishType
    JOIN `FinishTierPrice`
        ON FinishTierPrice.FinishOption_idFinishOption = FinishOption.idFinishOption
WHERE Product.idProduct = 1
    AND FinishTierPrice.idFinishTierPrice IN (SELECT FinishTierPrice.idFinishTierPrice
                                              FROM `FinishTierPrice` 
                                              WHERE FinishTierPrice.Qty <= a.Qty
                                              ORDER BY a.Qty DESC
                                              LIMIT 1)

1 Ответ

3 голосов
/ 20 августа 2010

Это разновидность проблемы greatest-n-per-group, которая часто возникает.

Требуется форма строки FinishTierPrice (назовите ее p1), соответствующая FinishOption и имеющая наибольшее кол-во, но все же меньшее или равное количеству кол-ва ProductOptionTier.

Один из способов сделать это - попытаться сопоставить вторую строку (p2) из FinishTierPrice, которая будет иметь такой же FinishOption и большее Qty. Если такой строки не существует (используйте внешнее соединение и проверьте, что она NULL), то строка, найденная p1, является наибольшей.

SELECT Product.Name, ProductOption.Name, a.Qty, a.Price, SheetSize.UpgradeCost,
        FinishType.Name, FinishOption.Name, FinishTierPrice.Qty, FinishTierPrice.Price
FROM `Product`
    JOIN `ProductOption`
        ON Product.idProduct = ProductOption.Product_idProduct
    JOIN `ProductOptionTier` AS a
        ON a.ProductOption_idProductOption = ProductOption.idProductOption
    JOIN `PaperSize`
        ON PaperSize.idPaperSize = ProductOption.PaperSize_idPaperSize
    JOIN `SheetSize`
        ON SheetSize.PaperSize_idPaperSize = PaperSize.idPaperSize
    JOIN `FinishOption`
        ON FinishOption.Product_idProduct = Product.idProduct
    JOIN `FinishType`
        ON FinishType.idFinishType = FinishOption.Finishtype_idFinishType
    JOIN `FinishTierPrice` AS p1
        ON p1.FinishOption_idFinishOption = FinishOption.idFinishOption
        AND p1.Qty <= a.Qty
    LEFT OUTER JOIN `FinishTierPrice` AS p2
        ON p2.FinishOption_idFinishOption = FinishOption.idFinishOption
        AND p2.Qty <= a.Qty AND (p2.Qty > p1.Qty OR p2.Qty = p1.Qty 
            AND p2.idFinishTierPrice > p1.idFinishTierPrice)
WHERE Product.idProduct = 1
    AND p2.idFinishTierPrice IS NULL
...