我有3张桌子
客户表
CustomerID, LastName,
交易表
TransID, CustomerID, Price,
付款表
PaymentID, CustomerID, Paid,
我正在尝试通过合并CustomerID
&来进行查询以获得总余额。 Price
& Paid
然后执行Price - Paid
并获得全额余额。
我试过了:
SELECT [Customers].LastName, SUM(Transactions.Price) AS [Total Price], SUM(Payments.Paid) AS [Total Paid], SUM(Transactions.Price - Payments.Paid) AS Balance
FROM ([Customers] LEFT JOIN Payments ON Payments.CustomerID = [Customers].CustomerID) LEFT JOIN Transactions ON Transactions.CustomerID = [Customers].CustomerID
GROUP BY [Customers].LastName;
但总实际Paid
金额与实际付款金额相比翻了一倍(例如:如果客户有150美元的余额,并支付65美元,则会显示总付费= 130美元,在结果中,它将使总余额为20美元而不是85美元。
查询结果
作为附注,如果已经付款,则总Balance
列仅向我提供余额。如果尚未针对特定CustomerID进行付款,则为空白而非当前余额金额。
请帮助!!!
答案 0 :(得分:3)
您可以尝试以下查询:
SELECT [A].LastName, (SUM(A.PaidAmt) - SUM(PriceAmt) ) AS Amt
FROM (
SELECT
[Customers].LastName, (Payments.Paid) as PaidAmt , 0 AS PriceAmt
FROM [Customers]
LEFT JOIN Payments
ON Payments.CustomerID = [Customers].CustomerID
UNION
SELECT
[Customers].LastName, 0 as PaidAmt , (Transactions.Price) AS PriceAmt
FROM [Customers]
LEFT JOIN Transactions
ON Transactions.CustomerID = [Customers].CustomerID
) A
GROUP BY A.LastName;
这应该有用。
答案 1 :(得分:0)
为什么你会获得双倍,三倍或更多的金额?问题是基数问题。如果付款和交易与客户的关系是1:M;并且除了客户之外,它们之间没有任何关系,那么当您不想要它们时,记录会被复制。假设我们有以下与客户1相关的记录数
您认为发生加入时发生的事情是:
+------------+----------+---------------+-------+-----------+------+--+-------+
| CustomerID | LastName | TransactionID | Price | PaymentID | Paid | | Total |
+------------+----------+---------------+-------+-----------+------+--+-------+
| 1 | Smith | 1 | 150 | 1 | 20 | | |
| 1 | Smith | 3 | 30 | 3 | 40 | | |
| | | | 180 | | 60 | | 120 |
当实际发生的事情是:(引擎不知道如何将付款与交易挂钩,因此必须将每笔交易与所有付款联系起来!)
+------------------------------------------------------------------------------
| CustomerID | LastName | TransactionID | Price | PaymentID | Paid | | Total |
| 1 | Smith | 1 | 150 | 1 | 20 | | |
| 1 | Smith | 1 | 150 | 3 | 40 | | |
| 1 | smith | 3 | 30 | 1 | 20 | | |
| 1 | smith | 3 | 30 | 3 | 40 | | 240 |
+------------+----------+---------------+-------+-----------+------+--+-------+
请注意,每个交易ID必须与付款ID配对,因此记录和金额加倍,或绊倒或翻两番,具体取决于解决交易和付款之间M:M所需的记录数。实际上由于没有定义关系,该表将所有客户支付记录交叉连接到所有客户交易记录。
现在,如果您有办法将交易与交易挂钩,以便它们是1:1的关系,那么我们就不需要子查询。但是,因为我怀疑你能做到这一点(客户可以支付部分款项;因此你需要支持1:M);我建议在连接之前在内联视图中进行总结。
当您加入这三个表时,您将获得4个记录而不是2. 1个客户记录* 2个付款记录* 2个交易= 4.现在每个付款对于交易中的每个记录都重复一次,因此如果2个交易,则支付10美元两次存在。要解决此问题,您必须在连接之前总计记录;从而产生1:1:1的关系,人工膨胀的数量/总数消失。
作为备注:您需要nz
(取第一个非空值)作为总价和支付的总金额,其中不包括客户的付款或交易。假设客户没有付款,当你拿到150 + 30时,你会得到180减去null并且你得到null。因此,新西兰对于处理客户没有支付或交易的情况非常重要。
SELECT c.LastName
, nz(T.[Total Price],0)
, nz(P.[Total Paid],0)
, nz(T.[Total Price],0)- nz(P.[Total Paid],0) AS Balance
FROM [Customers] c
LEFT JOIN (SELECT sum(Payments.paid) as [Total Paid], customerID
FROM payments
GROUP BY customerID ) p
ON P.CustomerID = c.CustomerID
LEFT JOIN (SELECT sum(Transactions.price) as [Total Price], customerID
FROM Transactions
GROUP BY customerID) t
ON t.CustomerID = c.CustomerID
答案 2 :(得分:0)
以下是绝对符合您要求的查询
select a.lastname,a.tot_payment,b.tot_trans,(b.tot_trans-a.tot_payment) as balance
from (select c.id,lastname,sum(p.price) tot_payment--,sum(t.price)
from customers c
left join payments p on c.id = p.custid
group by lastname,c.id) a
join
(select c.id,sum(t.price) tot_trans
from customers c
left join transactions t on t.custid = c.id
group by c.id)b
on a.id = b.id