连接两个在MS-Access中使用聚合的查询

时间:2019-03-30 20:40:15

标签: sql ms-access

这个问题要求我们联接多个表格,并显示每个帐户根据已下订单和付款所获得的余额。

由于特定于MS-Access的语法,您无法使用别名在from子句中联接两个查询。我尝试使用UNION功能,但似乎也无法正常工作。在下面,您可以看到我一直试图结合在一起的两个查询。

查询1

SELECT c.clientname, SUM(p.payment) AS Total_Paid

FROM clients c INNER JOIN payments p ON c.clientnumber = p.clientnumber

GROUP BY c.clientname

结果

[Client Name] [Total_Paid]
Client A           1000    
Client B           1500    
Client C           2000

查询2

SELECT c.clientname, SUM(i.orderamount * i.itemprice) AS Total_Owed

FROM (clients c INNER JOIN orders o ON c.clientnumber = o.clientnumber)

INNER JOIN orderinfo i ON i.ordernum = o.ordernum

GROUP BY c.clientname

结果

[Client Name] [Total_Owed]
Client A           1000    
Client B           2500    
Client C           3000

我希望得到的结果是一张表,该表是从总欠款中减去Total_Paid的结果,而只使用一个查询即可。

我尝试将查询作为起点运行

(SELECT c1.clientname, SUM(p.payment) AS Total_Paid

FROM clients c1 INNER JOIN payments p ON c1.clientnumber = p.clientnumber

GROUP BY c1.clientname)

UNION

(SELECT c.clientname, SUM(i.orderamount * i.itemprice) AS Total_Owed

FROM (clients c INNER JOIN orders o ON c.clientnumber = o.clientnumber)

INNER JOIN orderinfo i ON i.ordernum = o.ordernum

GROUP BY c.clientname)

但是我得到的结果是这样的

[Client Name] [Total_Paid]
Client A           1000
Client A           1000
Client B           1500
Client B           2500
Client C           2000
Client C           3000

代替

[Client Name] [Total_Owed][Total_Paid]
Client A          1000       1000 
Client B          2500       1500 
Client C          3000       2000

完成的结果应类似于

[Client Name] [Balance]
Client A          0 
Client B          1000 
Client C          2000

请让我知道是否需要澄清!

2 个答案:

答案 0 :(得分:1)

您有clientspaymentsordersorderinfo的表。看起来这些关系是{{1}上的clients JOIN到paymentsorders,而{{1}上的client_number JOIN到orders }}。因此,您将需要像上面一样将付款和订单汇总在一起,但您无需使用UNION,而需要将这两个汇总金额合并为派生表。这样一来,您就可以减去金额,而不是将其垂直堆叠在结果中。 JOIN可以添加相关表中的列,而UNION可以堆叠来自不同查询的相似结构化结果。由于所需的比较是并排的,因此您需要加入JOIN才能对计算得出的指标进行操作,就好像它们是同一行的一部分但在不同的列中一样。我使用LEFT JOIN并从orderinfo开始,因为我可以想象某人有可能在尚未付款的情况下订购,并且您希望看到该结果仍具有他们的全部余额。 INNER JOIN仅在客户既有订单又有付款的情况下产生结果。 Access不支持COALESCE()或CASE表达式,因此使用IIF()摆脱了没有付款的情况(这将是空的,因此不能用于减法)。

order_number

答案 1 :(得分:0)

我会这样写:

SELECT c.clientname, p.Total_Paid, o.Total_Owed
FROM (clients c LEFT JOIN
      (SELECT p.clientnumber, SUM(p.payment) AS Total_Paid
       FROM payments p
       GROUP BY p.clientnumber
      ) as p 
      ON c.clientnumber = p.clientnumber
     ) LEFT JOIN
     (SELECT o.clientnumber, SUM(oi.orderamount * oi.itemprice) AS Total_Owed
      FROM orders o INNER JOIN
           orderinfo oi
           ON oi.ordernum = o.ordernum
      GROUP BY o.clientnumber
     ) o
     ON c.clientnumber = o.clientnumber;

注意:这将返回所有个客户,即使是那些没有付款或没有订单的客户。这似乎是您要提出的问题。