SELECT 内的 SELECT 返回了超过 1 行

More than 1 rows returned from SELECT inside SELECT

我正在尝试创建一个查询来查找每个客户欠公司的总金额是多少。造成问题的是子查询中的 GROUP BY customerNumber

SELECT customerName,
       customers.customerNumber,
       SUM(quantityOrdered * priceEach) - ( SELECT SUM(amount) AS MoneyPayed FROM payments GROUP BY customerNumber ) AS AmountOwed
FROM payments
INNER JOIN customers ON payments.customerNumber = customers.customerNumber
INNER JOIN orders ON customers.customerNumber = orders.customerNumber
INNER JOIN  orderdetails ON  orders.orderNumber = orderdetails.orderNumber
GROUP BY customerNumber;

我正在尝试 link 的 table 是 paymentsorderdetails

当我去掉 GROUP BY 时,我得到的结果是负数,因为从 SUM(quantityOrdered * priceEach).

的每一行中减去总金额 SUM

如何更改此设置以便我可以从付款中 return 多行中减去订单详细信息 table 中的 SUM(quantityOrdered * priceEach)

Link 到数据库,因为 Whosebug 不允许我 post 图片

感谢帮助,如果格式不好请见谅,这是我的第一个post。

您将需要几个子查询来满足您的要求。让我们来分解一下。

首先,您需要每个客户的订单总价值。您非常接近正确的查询。应该是

               SELECT orders.customerNumber,
                      SUM(orderdetails.quantityOrdered * orderdetails.priceEach) owed
                 FROM orders
                 JOIN orderdetails ON  orders.orderNumber = orderdetails.orderNumber
             GROUP BY orders.customerNumber

该子查询的结果集给出了 customerNumber 和 owed,欠款金额。请注意,orders::orderdetails 是一个 one::many 关系,因此我们确定每个细节只计算一次,因此 SUM 将是正确的。

接下来我们需要每个客户支付的金额。这个子查询相当简单。

               SELECT customerNumber,
                      SUM(amount) paid
                 FROM payments
                GROUP BY customerNumber

现在针对您的问题中缺少的操作:我们需要将这两个子查询连接到您的客户 table。

SELECT customers.customerName, customers.customerNumber
       owed.owed - paid.paid balance
  FROM customers
  LEFT JOIN (
               SELECT orders.customerNumber,
                      SUM(orderdetails.quantityOrdered * orderdetails.priceEach) owed
                 FROM orders
                 JOIN orderdetails ON  orders.orderNumber = orderdetails.orderNumber
             GROUP BY orders.customerNumber
       ) paid ON customers.customerNumber = paid.customerNumber
  LEFT JOIN (
               SELECT customerNumber,
                      SUM(amount) paid
                 FROM payments
                GROUP BY customerNumber
       ) owed ON customers.customerNumber = owed.customerNumber

看看这是怎么回事?我们加入一个 table 和两个子查询。每个子查询在 table 中的每一行都有零行或一行,因此我们不需要在外部查询中使用 SUM 或 GROUP BY。

只剩下一个复杂问题:如果客户从未支付过任何费用怎么办?那么paid.paid的值在LEFT JOIN操作之后会是NULL。这将强制 owed - paid 的值为 NULL。所以我们需要在 SELECT 语句中使用更多的智能来产生正确的总和。

SELECT customers.customerName, customers.customerNumber
       COALESCE(owed.owed,0) - COALESCE(paid.paid,0) balance
       ...

COALESCE(a,b) 等同于 if a is not null then a else b.

专业提示 在包含 JOIN 操作的查询或子查询中,始终提及 table.column 而不仅仅是 column。下一个处理您查询的人会感谢您。