Я сделал все, что мог, чтобы описать свою проблему как можно подробнее; если есть вопросы, прокомментируйте и задавайте. Я понимаю, что, возможно, упустил очень простое решение, и мне интересно услышать, как я могу сделать это проще; При этом убедитесь, что ваш ответ учитывает все, что я описал, и вы задали все вопросы (и получили ответы), прежде чем публиковать свое решение.
Задний план
Две таблицы: orders
и items
, каждая из которых содержит уникальную информацию (они используют идентификаторы для связи друг с другом; повторяющиеся данные отсутствуют). См. Приложения A и B (ниже).
Таблица orders
(Приложение A) содержит всю информацию, уникальную для этого заказа. Каждый товар, добавленный в заказ, имеет свою собственную строку в таблице, содержащую идентификатор заказа, идентификатор товара и количество (и другие нерелевантные поля).
Проблема
Я создаю интерфейс, который позволит пользователю фильтровать заказы по следующим параметрам:
- количество позиций (товар)
- количество штук (количество товаров)
- Стоимость (общая стоимость заказа: количество товаров, умноженное на стоимость товара)
Мне кажется, что можно собрать все данные в один MySQL-запрос. Вот информация, которую мне нужно собрать:
- количество позиций в заказе
- идентификаторы предметов
- количество купленных (на продукт)
Пример
Пользователь хочет отфильтровать все заказы по следующим параметрам:
- три предмета (продукты)
- семь штук (общее количество)
- менее 600 долларов
Если бы все данные (заказ и элемент) содержались в одной таблице, запрос был бы примерно таким:
SELECT order_ID,
GROUP_CONCAT(item_ID) as item_IDs,
GROUP_CONCAT(quantity) as quantities,
SUM(price) as price
FROM orders
GROUP BY order_ID
HAVING 7 = SUM(quantity) AND
3 = COUNT(*)
и верните что-то вроде этого:
order_ID | item_IDs | quantities | price
=========================================
15 | 22,9,36 | 1,4,2 | $582
Но поскольку цена хранится в отдельной таблице, все сложнее. Я создал этот запрос (см. Приложение C):
SELECT DISTINCT o.order_ID,
GROUP_CONCAT(o.`item_ID`) as item_IDs,
GROUP_CONCAT(o.`quantity`) as quantities
FROM orders o
GROUP BY o.`order_ID`
HAVING 7 = SUM(o.`quantity`) AND
3 = COUNT(*)
ORDER BY o.`order_ID` DESC`
что приближает меня, но оставляет желать лучшего. Я пробовал использовать JOINS
(В чем разница между INNER JOIN, LEFT JOIN, RIGHT JOIN и FULL JOIN?), но в нерабочее время не удалось заставить что-либо работать.
Вопрос
Можно ли получить все эти данные в одном запросе MySQL и / или есть лучший способ, чем путь, по которому я сейчас иду (что бы вы сделали)?
Было бы приемлемо, если бы запрос возвращал результаты, подобные этому:
order_ID | item_ID | quantity | price
======================================
177 | 42 | 2 | 50.00
177 | 45 | 3 | 30.00
177 | 46 | 2 | 10.00
150 | 39 | 3 | 25.00
150 | 47 | 1 | 95.00
150 | 41 | 3 | 15.00
при условии, что запрос требовал, чтобы итоговые заказы состояли из трех и семи частей, а их общая сумма составляла менее 600 долларов США (в соответствии с приведенным примером).
Я также смирился с тем, что это может быть невозможно в рамках одного запроса, и я знаю, как сделать это с помощью PHP; подумал, что могу попробовать сделать большую часть этого в MySQL, насколько это возможно, и кое-чему научусь сегодня. :)
Некоторые из вас, вероятно, предложат изменить структуру таблицы, но я бы предпочел не иметь таблиц с повторяющимися данными, если это можно сделать: если цена продукта изменится, мне бы не пришлось обновлять за два таблицы.
Спасибо за ваше время и любые решения, которые у вас могут быть; Я очень благодарен вам за любую помощь.
Экспонаты / наглядные пособия
Приложение A: orders
Таблица
ID | order_ID | item_ID | quantity
======================================
1146 | 195 | 52 | 3
1145 | 195 | 1 | 4
1142 | 193 | 41 | 1
1141 | 193 | 40 | 3
1031 | 177 | 45 | 3
1032 | 177 | 46 | 2
1030 | 177 | 42 | 2
881 | 150 | 47 | 1
880 | 150 | 39 | 3
882 | 150 | 41 | 3
Приложение B: items
Таблица
(предоставлено для полноты, не критичной информации) https://cldup.com/ZQEDy-vef6.png
Приложение C: запрос и результаты
SELECT DISTINCT o.order_ID,
GROUP_CONCAT(o.`item_ID`) as item_IDs,
GROUP_CONCAT(o.`quantity`) as quantities
FROM orders o
GROUP BY o.`order_ID`
HAVING 7 = SUM(o.`quantity`) AND
3 = COUNT(*)
ORDER BY o.`order_ID` DESC
.
order_ID | item_IDs | quantities
=================================
177 | 42,45,46 | 2,3,2
150 | 39,47,41 | 3,1,3
115 | 39,47,41 | 3,1,3
108 | 48,45,46 | 2,3,2