Выбор дополнительных полей на основе SQL MIN()

#mysql #sql #min

#mysql #sql #min

Вопрос:

При использовании функции SQL MIN() я хочу выбрать любые дополнительные поля, соответствующие МИНИМАЛЬНОЙ строке. Следующий запрос возвращает правильное значение MIN (цена продажи), но не соответствует правильной строке в таблице product_price. Как я могу этого добиться?

 SELECT p.*, MIN(pp.sellPrice) AS sellPrice, pp.* FROM `product` AS p
LEFT JOIN `product_price_group` AS ppg ON p.`id` = ppg.`productId`
LEFT JOIN `product_price` AS pp ON ppg.`id` = pp.`priceGroupId`
WHERE p.`active` = 1 AND p.id = 1
  

Комментарии:

1. Что вы имеете в виду под match the correct row in the product_price table. ? Вы пытаетесь присоединиться к минимальной цене или что-то в этом роде? На самом деле я немного удивлен, что этот SQL вообще работает, поскольку у вас нет GROUP BY предложения….

2. Да, действительно, я пытаюсь присоединиться к минимальной цене, я хочу, чтобы другие поля принадлежали минимальной цене продажи.

Ответ №1:

То, что вы ищете, — это все строки, в которых нет более низкой цены:

 SELECT p.*, pp.sellPrice AS sellPrice, pp.* FROM `product` AS p
LEFT JOIN `product_price_group` AS ppg ON p.`id` = ppg.`productId`
LEFT JOIN `product_price` AS pp ON ppg.`id` = pp.`priceGroupId`
WHERE p.`active` = 1 AND p.id = 1
   AND NOT EXISTS (SELECT 1 FROM product_price AS pp2
       WHERE pp2.productId = pp.productId AND pp2.sellPrice < pp.sellPrice)
GROUP BY productId;
  

Я немного догадываюсь о том, какие ключи задействованы. Идея состоит в том, чтобы WHERE NOT EXISTS искать любые соответствующие строки с более низкими ценами. Таким образом, MySQL включит в ваши результаты только те строки, в которых не удалось найти соответствие «более низкой цене».

Ответ №2:

Вы хотите минимальную цену продажи для всех продуктов или для каждого продукта?

для всех продуктов

 SELECT p.*
     , pp.sellPrice
     , pp.*
FROM product AS p
LEFT JOIN product_price_group AS ppg
  ON p.id = ppg.productId
LEFT JOIN product_price AS pp
  ON ppg.id = pp.priceGroupId
WHERE p.active = 1
  AND p.id = 1
  AND pp.sellPrice =
    ( SELECT MIN(pp.sellPrice)
      FROM product_price
    )
  

для каждого продукта

 SELECT p.*
     , pp.sellPrice
     , pp.*
FROM product AS p
LEFT JOIN product_price_group AS ppg
  ON p.id = ppg.productId
LEFT JOIN product_price AS pp
  ON ppg.id = pp.priceGroupId
JOIN
  ( SELECT priceGroupId
         , pp.MIN(pp.sellPrice) AS sellPrice
    FROM product_price
    GROUP BY priceGroupId
  ) AS ppmin
  ON  ppmin.priceGroupId = pp.priceGroupId
  AND ppmin.sellPrice = sellPrice
WHERE p.active = 1
  AND p.id = 1
  

Ответ №3:

По некоторым предложениям я использовал атрибут GROUP BY, и следующий запрос работает правильно, если я хочу наименьшую цену продажи для определенного продукта:

 SELECT p.*, MIN(pp.sellPrice) AS sellPrice, pp.quantity, pp.`priceGroupId`
FROM `product` AS p
LEFT JOIN `product_price_group` AS ppg ON ppg.productId = p.`id`
LEFT JOIN `product_price` AS pp ON pp.priceGroupId = ppg.`id`
WHERE p.`active` = 1 AND  p.id = 1 AND pp.sellPrice IS NOT NULL
GROUP BY pp.id;
  

Для всех продуктов:

 SELECT p.*, MIN(pp.sellPrice) AS sellPrice, pp.quantity, pp.`priceGroupId`
FROM `product` AS p
LEFT JOIN `product_price_group` AS ppg ON ppg.productId = p.`id`
LEFT JOIN `product_price` AS pp ON pp.priceGroupId = ppg.`id`
WHERE p.`active` = 1 AND pp.sellPrice IS NOT NULL
GROUP BY pp.id;