如何在不生成 'combinatorial explosion' - MySQL 的情况下连接表
How to Join tables without generating a 'combinatorial explosion' - MySQL
我正在处理一个名为 classicmodels 的数据库。您可以在以下位置找到它:https://www.mysqltutorial.org/mysql-sample-database.aspx/
该公司销售微缩模型,产品分布在 7 个产品系列中:老爷车、老爷车、飞机、卡车和公共汽车、飞机、火车和摩托车。
我想了解哪些是 2003 年和 2004 年最畅销的产品线(以销售量和收入计)。
此外,我需要排除已取消的订单。这是由 'orders' table 中的 'status' 列告知的。
所以,显然,我们必须连接三个 tables:'products'(按每个产品线对结果进行分组),'orderdetails'(以获得销售数量和每个产品的价格单位)和 'orders'(过滤结果:select 仅 2003 年和 2004 年并排除已取消的订单)。
此外,需要说明的是,我们必须处理 1:M(一对多)对来解决这个问题,以避免 combinatorial/cartesian 爆炸。
products --> orderdetails 是一个 1:M 关系
orderdetails --> orders 是一个 1:M 关系
考虑到这一点,我决定创建子查询来建立 1:1 关系。因此,我计算了订购数量和每个产品线的总价值:
SELECT p.productLine, SUM(od.quantityOrdered) AS total_units, SUM(od.quantityOrdered*od.PriceEach) AS total_value
FROM products p
JOIN
orderdetails od ON p.productCode=od.productCode
GROUP BY p.productLine
ORDER BY total_value DESC;
结果如下:
现在,我不知道如何将上述子查询生成的table 与'orders' table 连接起来。这是因为它们没有任何可以在 JOIN 中使用的公共列。
如何确定 2003 年和 2004 年最畅销的产品线(以销售量和收入计),不包括取消的订单?
您可以在下面检查数据库的关系模式:
只需添加另一个 JOIN
与 orders
table 和 WHERE
条件以限制您想要的订单。
SELECT p.productLine, SUM(od.quantityOrdered) AS total_units, SUM(od.quantityOrdered*od.PriceEach) AS total_value
FROM products p
JOIN orderdetails od ON p.productCode=od.productCode
JOIN orders o ON o.orderNumber = od.orderNumber
WHERE o.orderDate BETWEEN '2003-01-01' AND '2004-12-31'
AND o.status != 'cancelled'
GROUP BY p.productLine
ORDER BY total_value DESC;
您不想将您在 orders
table 上的结果加入 before[=] 20=] 您汇总了结果。
这只是将另一个连接添加到 JOIN
列表的末尾,然后使用 WHERE
子句进行过滤,然后像您已经做的那样聚合...
SELECT
p.productLine,
SUM(od.quantityOrdered) AS total_units,
SUM(od.quantityOrdered*od.PriceEach) AS total_value
FROM
products p
INNER JOIN
orderdetails od
ON p.productCode = od.productCode
INNER JOIN
orders o
ON o.orderNumber = od.orderNumber
WHERE
o.status != 'Cancelled'
AND o.orderDate >= '2003-01-01'
AND o.orderDate < '2005-01-01' -- Less than the next year, in case the date includes a time
GROUP BY
p.productLine
ORDER BY
total_value DESC;
我正在处理一个名为 classicmodels 的数据库。您可以在以下位置找到它:https://www.mysqltutorial.org/mysql-sample-database.aspx/
该公司销售微缩模型,产品分布在 7 个产品系列中:老爷车、老爷车、飞机、卡车和公共汽车、飞机、火车和摩托车。
我想了解哪些是 2003 年和 2004 年最畅销的产品线(以销售量和收入计)。
此外,我需要排除已取消的订单。这是由 'orders' table 中的 'status' 列告知的。
所以,显然,我们必须连接三个 tables:'products'(按每个产品线对结果进行分组),'orderdetails'(以获得销售数量和每个产品的价格单位)和 'orders'(过滤结果:select 仅 2003 年和 2004 年并排除已取消的订单)。
此外,需要说明的是,我们必须处理 1:M(一对多)对来解决这个问题,以避免 combinatorial/cartesian 爆炸。
products --> orderdetails 是一个 1:M 关系
orderdetails --> orders 是一个 1:M 关系
考虑到这一点,我决定创建子查询来建立 1:1 关系。因此,我计算了订购数量和每个产品线的总价值:
SELECT p.productLine, SUM(od.quantityOrdered) AS total_units, SUM(od.quantityOrdered*od.PriceEach) AS total_value
FROM products p
JOIN
orderdetails od ON p.productCode=od.productCode
GROUP BY p.productLine
ORDER BY total_value DESC;
结果如下:
现在,我不知道如何将上述子查询生成的table 与'orders' table 连接起来。这是因为它们没有任何可以在 JOIN 中使用的公共列。
如何确定 2003 年和 2004 年最畅销的产品线(以销售量和收入计),不包括取消的订单?
您可以在下面检查数据库的关系模式:
只需添加另一个 JOIN
与 orders
table 和 WHERE
条件以限制您想要的订单。
SELECT p.productLine, SUM(od.quantityOrdered) AS total_units, SUM(od.quantityOrdered*od.PriceEach) AS total_value
FROM products p
JOIN orderdetails od ON p.productCode=od.productCode
JOIN orders o ON o.orderNumber = od.orderNumber
WHERE o.orderDate BETWEEN '2003-01-01' AND '2004-12-31'
AND o.status != 'cancelled'
GROUP BY p.productLine
ORDER BY total_value DESC;
您不想将您在 orders
table 上的结果加入 before[=] 20=] 您汇总了结果。
这只是将另一个连接添加到 JOIN
列表的末尾,然后使用 WHERE
子句进行过滤,然后像您已经做的那样聚合...
SELECT
p.productLine,
SUM(od.quantityOrdered) AS total_units,
SUM(od.quantityOrdered*od.PriceEach) AS total_value
FROM
products p
INNER JOIN
orderdetails od
ON p.productCode = od.productCode
INNER JOIN
orders o
ON o.orderNumber = od.orderNumber
WHERE
o.status != 'Cancelled'
AND o.orderDate >= '2003-01-01'
AND o.orderDate < '2005-01-01' -- Less than the next year, in case the date includes a time
GROUP BY
p.productLine
ORDER BY
total_value DESC;