Предполагая, что вы хотите максимизировать калории / цену, я думаю, что можно выполнимо. Хитрость заключается в том, что для конкретного продукта вы максимизируете калории / цену, накапливая надстройки в порядке убывания соотношения калорий / цены, пока общее соотношение не начнет уменьшаться.
Следующий запрос, вероятно, смехотворно неэффективен и нуждается в серьезной оптимизации, но, по крайней мере, показывает, что решение существует:
SELECT
p.name AS product,
GROUP_CONCAT(a.name) AS additives,
p.price + COALESCE(SUM(a.price), 0) AS price,
p.calories + COALESCE(SUM(a.added_calories), 0) AS calories,
(p.calories + COALESCE(SUM(a.added_calories), 0)) /
(p.price + COALESCE(SUM(a.price), 0)) AS calories_per_price
FROM
products AS p
LEFT JOIN connector AS c ON c.product = p.id
LEFT JOIN additives AS a
ON a.id = c.additive
AND (a.added_calories / a.price) > (
(p.calories + COALESCE((
SELECT SUM(b.added_calories) FROM connector AS d, additives AS b
WHERE d.product = p.id AND b.id = d.additive
AND (b.added_calories / b.price) > (a.added_calories / a.price)
), 0)) /
(p.price + COALESCE((
SELECT SUM(b.price) FROM connector AS d, additives AS b
WHERE d.product = p.id AND b.id = d.additive
AND (b.added_calories / b.price) > (a.added_calories / a.price)
), 0))
)
GROUP BY p.id
ORDER BY calories_per_price DESC
LIMIT 10;
Редактировать: ОК, я его отладил, теперь он действительно работает (!). Вот некоторые тестовые данные:
INSERT INTO products (id, name, calories, price) VALUES
(1, 'Cardboard', 0, 1),
(2, 'Lard', 1000, 100),
(3, 'Spaghetti', 10, 50);
INSERT INTO additives (id, name, added_calories, price) VALUES
(1, 'Salt', 0, 2),
(2, 'Butter', 500, 100),
(3, 'Cheese', 300, 70),
(4, 'Pepper', 0, 3),
(5, 'Ketchup', 50, 10),
(6, 'Milk', 20, 10);
INSERT INTO connector (product, additive) VALUES
(1,1), (1,2), (1,3), (1,4), (1,5), (1,6),
(2,1), (2,3), (2,4), (2,5),
(3,1), (3,2), (3,3), (3,4), (3,5);
И результаты:
+-----------+-----------------------+-------+----------+--------------------+
| product | additives | price | calories | calories_per_price |
+-----------+-----------------------+-------+----------+--------------------+
| Lard | NULL | 100 | 1000 | 10 |
| Cardboard | Butter,Ketchup | 111 | 550 | 4.95495495495495 |
| Spaghetti | Butter,Cheese,Ketchup | 230 | 860 | 3.73913043478261 |
+-----------+-----------------------+-------+----------+--------------------+
Редактировать 2: Упс, у меня была максимальная цена за калории вместо калорий за цену. Исправлено.
Редактировать 3: Подзапросы игнорировали таблицу соединителей. Я (надеюсь) исправил эту ошибку, но пока не смог ее проверить.