sql—如何在不生成“组合爆炸”的情况下联接表—mysql

ylamdve6  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(435)

我正在开发一个名为classicmodels的数据库。您可以在以下网址找到:https://www.mysqltutorial.org/mysql-sample-database.aspx/
这家公司销售的微型模型,分布在7个产品线:经典汽车,老式汽车,飞机,卡车和公共汽车,飞机,火车和摩托车。
我想找出2003年和2004年最畅销的产品线(销售单位和收入)。
另外,我需要排除已取消的订单。这是由“订单”表中的“状态”列通知的。
因此,很显然,我们必须连接三个表:“产品”(按每个产品线对结果进行分组)、“订单详细信息”(获取销售数量和单位价格)和“订单”(过滤结果:仅选择2003和2004,排除取消的订单)。
此外,为了避免组合/笛卡尔爆炸,我们必须处理1:m(一对多)对来解决这个问题。
产品-->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;

结果如下:

现在,我不知道如何将上面的子查询生成的表与'orders'表连接起来。这是因为它们没有任何可以在联接中使用的公共列。
我如何确定2003年和2004年最畅销的产品线(销售单位和收入),不包括取消的订单?
您可以在下面检查数据库的关系模式:

nszi6y05

nszi6y051#

你不想把你的结果加入到 orders 表中,您希望在聚合结果之前执行该联接。
这只是将另一个连接添加到列表的末尾 JOIN s、 然后用过滤器过滤 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;
ws51t4hk

ws51t4hk2#

再加一个 JOINorders 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;

相关问题