I have to tables. products
table and product_variants
table. In product table
, I have
id, product_name, photo
.
In product_variants
table, I have
id, product_id, packet_size, price
.
I have to add products first, then will add variants. It is possible that no variants have been added for that.
I want to fetch all the product with one variant details from variants table with the lowest price.
Example scenario:
products table
id product_name photo
1 product_1 1.png
2 product_2 2.png
3 product_3 3.png
4 product_4 4.png
product_variants
id product_id packet_size price
1 1 100 ML 50 RS.
2 1 200 ML 100 Rs.
3 1 300 ML 150 RS.
4 2 300 L 300 Rs.
5 2 200 L 200 Rs.
6 3 200 K 200 Rs.
I want the result to be as below:
1 product_1 1.png 100 ML 50 RS.
2 product_2 2.png 200 L 200 Rs.
3 product_3 3.png 200 K 200 Rs.
Thanks.
Based on all the other questions your can find for "mysql join group min" or "mysql join group max" there are some catches when using GROUP BY and MIN/MAX and JOINs. You can use the following approach:
For step 1 the query will look like this:
SELECT
product_id,
MIN(price) as price
FROM
product_variants
GROUP BY
product_id
This will result in the following output (ids may differ):
+------------+-------+
| product_id | price |
+------------+-------+
| 1 | 50 |
| 2 | 200 |
| 4 | 200 |
+------------+-------+
For step 2 we use this result in a JOIN query on itself:
SELECT
v2.product_id,
v2.packet_size,
v2.price
FROM
product_variants v2
JOIN
(SELECT -- here is your first query
product_id,
MIN(price) as price
FROM
product_variants
GROUP BY
product_id
) v1 -- notice the "v1" alias here, its needed
USING (product_id, price)
The result will be:
+------------+-------------+-------+
| product_id | packet_size | price |
+------------+-------------+-------+
| 1 | 100 ML | 50 |
| 2 | 200 L | 200 |
| 4 | 200 L | 200 |
+------------+-------------+-------+
And for step 3 it's just a "normal" JOIN between two tables:
SELECT
p.id,
p.product_name,
p.photo,
v3.packet_size,
v3.price
FROM
products p
JOIN
(SELECT -- here is query 2
v2.product_id,
v2.packet_size,
v2.price
FROM
product_variants v2
JOIN
(SELECT -- here is query 1
product_id,
MIN(price) as price
FROM
product_variants
GROUP BY product_id
) v1
USING (product_id, price)
) v3
ON
p.id = v3.product_id;
And this will get you the following result (again ids may differ):
+----+--------------+-------+-------------+-------+
| id | product_name | photo | packet_size | price |
+----+--------------+-------+-------------+-------+
| 1 | product_1 | 1.png | 100 ML | 50 |
| 2 | product_2 | 2.png | 200 L | 200 |
| 4 | product_3 | 3.png | 200 L | 200 |
+----+--------------+-------+-------------+-------+
And if you use a LEFT JOIN instead of a "normal" JOIN, you get products as well which doesn't have any variants:
+----+--------------+-------+-------------+-------+
| id | product_name | photo | packet_size | price |
+----+--------------+-------+-------------+-------+
| 1 | product_1 | 1.png | 100 ML | 50 |
| 2 | product_2 | 2.png | 200 L | 200 |
| 4 | product_3 | 3.png | 200 L | 200 |
| 5 | product_4 | 4.png | NULL | NULL |
+----+--------------+-------+-------------+-------+
The big catch is to fetch the remaining info of a found variant. You cannot do this in one query because the group function will fetch the correct value, but the other column values after the GROUP BY will not be from the found group function value, but instead will be most likely from the first row in the group.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.