I have these tables:
Product_variants as PV
CREATE TABLE `product_variants` (
`id` int(11) UNSIGNED NOT NULL,
`product_id` int(11) UNSIGNED NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Products as P
CREATE TABLE `products` (
`id` int(11) UNSIGNED NOT NULL,
`brand_id` int(11) UNSIGNED DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Order_items as OI
CREATE TABLE `order_items` (
`id` int(11) NOT NULL,
`order_id` int(11) UNSIGNED NOT NULL,
`product_variant_id` int(11) UNSIGNED DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Also orders and brands, which I assume are not needed for this example.
I would like obtain 15 rows where there will be 5 best-selling brands and three variants of them, sorted by marketability of brands and variants.
Expected
product_variant_id brand_id number_brands_sold number_variant_sold
1 1 100 50
2 1 100 30
3 1 100 10
4 2 90 40
5 2 90 25
6 2 90 10
7 3 80 45
8 3 80 20
9 3 80 5
10 4 60 25
11 4 60 20
12 4 60 8
13 5 40 10
14 5 40 9
15 5 40 8
I can get variants based on variants sold, but I can’t figure out how to incorporate brand sales into the query. Can it be that simple at all?
SELECT `pv`.`id` AS `product_variant_id`, `p`.`brand_id`, COUNT(DISTINCT `oi`.`order_id`) AS `number_variant_sold`
FROM `product_variants` as pv
LEFT JOIN `products` AS `p` ON p.id = pv.product_id
LEFT JOIN `order_items` AS `oi` ON oi.product_variant_id = pv.id
GROUP BY `pv`.`id`
ORDER BY `number_variant_sold` DESC
LIMIT 15
This query only returns 1 in number_brand_sold and does not return correct results without DISTINCT. Additionally, it will always sort by number_brand_sold first and then number_variant_sold. I would need it to work according to the "Expected" table.
SELECT `pv`.`id` AS `product_variant_id`, `p`.`brand_id`, COUNT(`p`.`brand_id`) AS `number_brand_sold`, COUNT(DISTINCT `oi`.`order_id`) AS `number_variant_sold`
FROM `product_variants` as pv
LEFT JOIN `products` AS `p` ON p.id = pv.product_id
LEFT JOIN `order_items` AS `oi` ON oi.product_variant_id = pv.id
GROUP BY `pv`.`id`
ORDER BY `number_variant_sold` DESC
LIMIT 15
EDIT:
I tried ask Chat GPT, but I did not get satisfactory answer. It seems that in mysql 5 it cannot be solved with one query. I couldn’t find a solution even by splitting it into 2 queries.
2
Answers
This will be something near this:
Possible disadvantage – if 5th and 6th brands have the same total amount then both of them they will be returned.
One more disadvantage – if 3rd and 4th variants have the same amount then one unpredictable of them will be returned.
But there is no additional criteria in any of the above cases.
You could do with some temporary tables.
A script like this should collate the counts, store the top 5 brands and run 2 queries.
At this point, it might be simpler to stop and to use the two query outputs separately. You could however, rewrite the last query:
This still does not impose your 3 variant limit.
For that, you could create a third temporary table:
Then iterate through results: