如何在不产生“组合爆炸”的情况下连接表 - MySQL

问题描述

我正在研究一个名为 classicmodels 的数据库。您可以在以下位置找到它:https://www.mysqltutorial.org/mysql-sample-database.aspx/

这家公司销售微型模型,这些模型分布在 7 个产品线中:老爷车、老爷车、飞机、卡车和公共汽车、飞机、火车和摩托车。

我想找出 2003 年和 2004 年最畅销的产品线(销量和收入)。

此外,我需要排除已取消的订单。这是由“订单”表中的“状态”列通知的。

因此,显然,我们必须加入三个表:“products”(按每个产品线对结果进行分组)、“orderdetails”(获取销售数量和单位价格)和“orders”(过滤结果) : 仅选择 2003 和 2004 并排除取消的订单)。

此外,有必要声明我们将不得不处理 1:M(一对多)对来解决这个问题,以避免组合/笛卡尔爆炸。

  • products --> orderdetails 是 1:M 关系

  • orderdetails --> 订单是 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;

结果如下:

enter image description here

现在,我不知道如何将上面子查询生成的表与 'orders' 表连接起来。这是因为它们没有任何可以在 JOIN 中使用的公共列。

如何确定 2003 年和 2004 年最畅销的产品线(以销量和收入计),不包括取消的订单?

您可以在下面检查数据库的关系模式:

enter image description here

解决方法

只需在 JOIN 表和 orders 条件中添加另一个 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 表中,而是希望在聚合结果之前加入.

这只是在 JOIN 列表的末尾添加另一个连接,然后使用 WHERE 子句进行过滤,然后按原样聚合...

SELECT
  p.productLine,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;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...