D
D
Denis Shpuganich2018-05-11 10:15:46
MySQL
Denis Shpuganich, 2018-05-11 10:15:46

How to join rows from another table with minimum value?

Given:
1) Products tableproduct

| id |  title  |
| 1  |продукт 1|
| 2  |продукт 2|

2) Supplier price tablesupplier_price
|product_id|supplier_id|price|
|    1     |     1     | 10  |
|    1     |     2     | 5   |
|    2     |     1     | 15  |

Task:
Select all product fields with minimum prices and corresponding supplier ids:
|product_id|supplier_id|price| id |  title  |
|    1     |     2     | 5   | 1  |продукт 1|
|    2     |     1     | 15  | 2  |продукт 2|

What have I tried?
1) Used JOIN
SELECT
    supplier_product.product_id,
    supplier_product.supplier_id,
    MIN(supplier_product.price)
FROM product
LEFT JOIN supplier_product ON product.id = supplier_product.product_id
group by supplier_product.product_id, supplier_product.supplier_id
#group by supplier_product.product_id

Problem:
If you add the supplier_id field to group by, products with different suppliers are doubled in the selection.
If not added (turn off full_only_group_by in sql_mode), then the supplier_id and price values ​​​​will not be consistent (the muscle randomly selects a value)
2) Used a nested SELECT
SELECT 
    product.*, 
    min_price
FROM product 
LEFT JOIN (
    SELECT 
        supplier_product.product_id,
        MIN(supplier_product.price) AS min_price
    FROM supplier_product
    GROUP BY supplier_product.product_id
  ) AS sp
ON product.id = sp.product_id

Problem: Essentially the same. I get the minimum price, but there is no supplier associated with it.
So is there a way to make the muscle group correctly?
That is, when choosing the minimum price, it takes the corresponding supplier id values

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
Rsa97, 2018-05-11
@dyonis

SELECT `p`.`product_id`, `p`.`supplier_id`, `p`.`price`, `i`.`title`
  FROM (
    SELECT `product_id`, MIN(`price`) AS `price`
      FROM `supplier_price`
      GROUP BY `product_id`
  ) AS `mp`
  JOIN `supplier_price` AS `p` ON `p`.`product_id` = `mp`.`product_id`
    AND `p`.`price` = `mp`.`price`
  JOIN `product` AS `i` ON `i`.`id` = `mp`.`product_id`

Or via ROLLUP
SELECT `p`.`product_id`, `p`.`supplier_id`, `p`.`price`, `i`.`title`
  FROM (
    SELECT `product_id`, `supplier_id`, `price`
      FROM `supplier_price`
      GROUP BY `product_id`, `supplier_id`, `price` WITH ROLLUP
      HAVING `price` = MIN(`price`)
  ) AS `p`
  JOIN `product` AS `i` ON `i`.`id` = `mp`.`product_id`

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question