如何为订单及其项目编写自定义 MySQL select 查询
How to write custom MySQL select query for orders and their items
我已尽我所能尽可能完整地描述我的问题;如果您有任何问题,请发表评论并提问。我知道我可能错过了一个非常简单的解决方案,并且很想听听如何使它更简单;也就是说,请确保您的回答考虑了我所描述的所有内容,并且在发布您的解决方案之前您已经提出了所有问题(并收到了答案)。
背景
两个 table:orders
和 items
,每个都包含唯一的信息(它们使用 ID 相互连接;没有重复数据)。请参阅附件 A 和 B(下方)。
orders
table(附件 A)包含该订单的所有独特信息。添加到订单的每个项目在 table 中都有自己的行,其中包含订单 ID、项目 ID 和数量(以及其他不相关的字段)。
问题
我正在构建一个界面,允许用户通过以下参数过滤订单:
- 项目数(产品)
- 件数(产品数量)
- 成本(总订单成本:产品数量乘以产品成本)
在我看来,在单个 MySQL 查询中收集所有数据应该是可能的。这是我需要收集的信息:
- 每个订单的商品数量
- 项目 ID
- 购买数量(每个产品)
例子
用户希望按以下规格过滤所有订单:
- 三项(产品)
- 七件(总量)
- 不到 600 美元
如果所有数据(订单和项目)都包含在一个 table 中,查询将是这样的:
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(*)
和 return 是这样的:
order_ID | item_IDs | quantities | price
=========================================
15 | 22,9,36 | 1,4,2 | 2
但由于价格存储在单独的 table 中,因此比较复杂。我创建了这个查询(参见图表 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
(What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN?),但几个小时后无法正常工作。
问题
是否可以在一个 MySQL 查询中检索所有这些数据,and/or 有没有比我目前所走的路径更好的方法(你会怎么做)?
接受table 查询 return 结果类似于:
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
只要查询要求生成的订单包含 3 件商品和 7 件商品,并且总计少于 600 美元(根据提供的示例)。
我也很遗憾这在一个查询中可能无法实现,并且我知道如何使用 PHP 来完成此操作;我想我可能会尝试在 MySQL 中尽可能多地做这件事,并在今天学到一些东西。 :)
你们中的一些人可能会建议更改 table 结构,但我真的不想让 table 包含重复数据,如果有帮助的话:如果产品价格发生变化,我宁愿不必在 table 秒后更新。
感谢您抽出宝贵时间以及您可能有的任何解决方案;我非常感谢你们能提供的任何帮助。
Exhibits/Visual 艾滋病
图表 A:orders
Table
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
Table
(为完整性提供,而非关键信息)
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
图表 D:SQLFiddle
我就从这里开始,一步步完成。
首先是 LEFT JOIN 是你的朋友。这样就可以得到每件商品的价格
示例 1:
通过此查询,您可以获得 table 个订单的前 100 行,包括每个订单的价格。
SELECT o.order_ID,
o.item_ID as item_ID,
o.quantity as quantitie,
i.price
FROM orders o
LEFT JOIN items i ON o.item_ID = i.id
ORDER BY o.order_ID
LIMI 100;
示例 2:
现在您的查询必须分成两部分。首先,我们将获得所有符合您的标准(商品、件数和价格)的订单 ID
SELECT o.order_ID
FROM orders o
LEFT JOIN items i ON o.item_ID = i.id
GROUP BY o.order_ID
HAVING
SUM(o.`quantity`) =7
AND
SUM(1) = 3
AND
SUM(i.price) < 700;
ORDER BY o.order_ID;
示例 3:
现在他拥有所有 order_ids 并且可以合并两个查询。
SELECT o.order_ID,
o.item_ID as item_ID,
o.quantity as quantitie,
i.price
FROM orders o
LEFT JOIN items i ON o.item_ID = i.id
where o.order_ID IN (
SELECT o.order_ID
FROM orders o
LEFT JOIN items i ON o.item_ID = i.id
GROUP BY o.order_ID
HAVING
SUM(o.`quantity`) =7
AND
SUM(1) = 3
AND
SUM(i.price) < 700 )
ORDER BY o.order_ID, o.quantity, i.price;
但是这不是testet。如果您通过 sqlfidle 放置一些示例日期,那么我可以直接为您测试它。
示例 4
我已将最后一个查询更改为 LEFT JOINS,但它不适用于 fiddle。我超时了。请检查您的服务器。
我还看到您的表上没有好的索引。所以查询会非常慢
SELECT mo.order_ID,
mo.item_ID ,
mo.quantity,
mi.price
FROM (
SELECT o.order_ID
FROM orders o
LEFT JOIN items i ON o.item_ID = i.id
GROUP BY o.order_ID
HAVING
SUM(o.`quantity`) =7
AND
SUM(1) = 3
AND
SUM(i.price) < 700
) AS ord
LEFT JOIN orders mo ON ord.order_ID = mo.order_ID
LEFT JOIN items mi ON mo.item_ID = mi.id
ORDER BY ord.order_id, mo.quantity, mi.price;
结果
+----------+---------+----------+--------+
| order_ID | item_ID | quantity | price |
+----------+---------+----------+--------+
| 115 | 47 | 1 | 30.00 |
| 115 | 41 | 3 | 42.00 |
| 115 | 39 | 3 | 60.00 |
| 150 | 47 | 1 | 30.00 |
| 150 | 41 | 3 | 42.00 |
| 150 | 39 | 3 | 60.00 |
| 177 | 46 | 2 | 120.00 |
| 177 | 42 | 2 | 120.00 |
| 177 | 45 | 3 | 180.00 |
+----------+---------+----------+--------+
9 rows in set (0.06 sec)
我已尽我所能尽可能完整地描述我的问题;如果您有任何问题,请发表评论并提问。我知道我可能错过了一个非常简单的解决方案,并且很想听听如何使它更简单;也就是说,请确保您的回答考虑了我所描述的所有内容,并且在发布您的解决方案之前您已经提出了所有问题(并收到了答案)。
背景
两个 table:orders
和 items
,每个都包含唯一的信息(它们使用 ID 相互连接;没有重复数据)。请参阅附件 A 和 B(下方)。
orders
table(附件 A)包含该订单的所有独特信息。添加到订单的每个项目在 table 中都有自己的行,其中包含订单 ID、项目 ID 和数量(以及其他不相关的字段)。
问题
我正在构建一个界面,允许用户通过以下参数过滤订单:
- 项目数(产品)
- 件数(产品数量)
- 成本(总订单成本:产品数量乘以产品成本)
在我看来,在单个 MySQL 查询中收集所有数据应该是可能的。这是我需要收集的信息:
- 每个订单的商品数量
- 项目 ID
- 购买数量(每个产品)
例子
用户希望按以下规格过滤所有订单:
- 三项(产品)
- 七件(总量)
- 不到 600 美元
如果所有数据(订单和项目)都包含在一个 table 中,查询将是这样的:
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(*)
和 return 是这样的:
order_ID | item_IDs | quantities | price
=========================================
15 | 22,9,36 | 1,4,2 | 2
但由于价格存储在单独的 table 中,因此比较复杂。我创建了这个查询(参见图表 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
(What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN?),但几个小时后无法正常工作。
问题
是否可以在一个 MySQL 查询中检索所有这些数据,and/or 有没有比我目前所走的路径更好的方法(你会怎么做)?
接受table 查询 return 结果类似于:
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
只要查询要求生成的订单包含 3 件商品和 7 件商品,并且总计少于 600 美元(根据提供的示例)。
我也很遗憾这在一个查询中可能无法实现,并且我知道如何使用 PHP 来完成此操作;我想我可能会尝试在 MySQL 中尽可能多地做这件事,并在今天学到一些东西。 :)
你们中的一些人可能会建议更改 table 结构,但我真的不想让 table 包含重复数据,如果有帮助的话:如果产品价格发生变化,我宁愿不必在 table 秒后更新。
感谢您抽出宝贵时间以及您可能有的任何解决方案;我非常感谢你们能提供的任何帮助。
Exhibits/Visual 艾滋病
图表 A:orders
Table
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
Table
(为完整性提供,而非关键信息) 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
图表 D:SQLFiddle
我就从这里开始,一步步完成。
首先是 LEFT JOIN 是你的朋友。这样就可以得到每件商品的价格
示例 1:
通过此查询,您可以获得 table 个订单的前 100 行,包括每个订单的价格。
SELECT o.order_ID,
o.item_ID as item_ID,
o.quantity as quantitie,
i.price
FROM orders o
LEFT JOIN items i ON o.item_ID = i.id
ORDER BY o.order_ID
LIMI 100;
示例 2:
现在您的查询必须分成两部分。首先,我们将获得所有符合您的标准(商品、件数和价格)的订单 ID
SELECT o.order_ID
FROM orders o
LEFT JOIN items i ON o.item_ID = i.id
GROUP BY o.order_ID
HAVING
SUM(o.`quantity`) =7
AND
SUM(1) = 3
AND
SUM(i.price) < 700;
ORDER BY o.order_ID;
示例 3:
现在他拥有所有 order_ids 并且可以合并两个查询。
SELECT o.order_ID,
o.item_ID as item_ID,
o.quantity as quantitie,
i.price
FROM orders o
LEFT JOIN items i ON o.item_ID = i.id
where o.order_ID IN (
SELECT o.order_ID
FROM orders o
LEFT JOIN items i ON o.item_ID = i.id
GROUP BY o.order_ID
HAVING
SUM(o.`quantity`) =7
AND
SUM(1) = 3
AND
SUM(i.price) < 700 )
ORDER BY o.order_ID, o.quantity, i.price;
但是这不是testet。如果您通过 sqlfidle 放置一些示例日期,那么我可以直接为您测试它。
示例 4
我已将最后一个查询更改为 LEFT JOINS,但它不适用于 fiddle。我超时了。请检查您的服务器。
我还看到您的表上没有好的索引。所以查询会非常慢
SELECT mo.order_ID,
mo.item_ID ,
mo.quantity,
mi.price
FROM (
SELECT o.order_ID
FROM orders o
LEFT JOIN items i ON o.item_ID = i.id
GROUP BY o.order_ID
HAVING
SUM(o.`quantity`) =7
AND
SUM(1) = 3
AND
SUM(i.price) < 700
) AS ord
LEFT JOIN orders mo ON ord.order_ID = mo.order_ID
LEFT JOIN items mi ON mo.item_ID = mi.id
ORDER BY ord.order_id, mo.quantity, mi.price;
结果
+----------+---------+----------+--------+
| order_ID | item_ID | quantity | price |
+----------+---------+----------+--------+
| 115 | 47 | 1 | 30.00 |
| 115 | 41 | 3 | 42.00 |
| 115 | 39 | 3 | 60.00 |
| 150 | 47 | 1 | 30.00 |
| 150 | 41 | 3 | 42.00 |
| 150 | 39 | 3 | 60.00 |
| 177 | 46 | 2 | 120.00 |
| 177 | 42 | 2 | 120.00 |
| 177 | 45 | 3 | 180.00 |
+----------+---------+----------+--------+
9 rows in set (0.06 sec)