用 SUM 从 parent table 中减去值(child table 中的值)

Subtracting value from parent table with SUM(value from child table)

我有 2 个 table,tblBasicInfotblPayment

关系是一对多,其中tblBasicInfo在1方,tblPaymentmany方。

关系是可选的,这就是问题所在。

我需要用 child table 中符合特定条件的特定字段的总和从 parent table 中减去特定字段的值。

如果 child table 中没有满足条件的记录,则应用零表示 (data from parent table - 0)。

如果这不是crystal清楚,我深表歉意,英语不是我的母语,我的经验不足,不知道如何正确描述问题。

最好用一个小例子来证明我的意思:

我们将从 table 模式开始:

tblBasicInfo: #ID, TotalPrice (double)

tblPayment: #P_ID, $ID, Amount (double), IsPaid (bool)

这里是 parent table tblBasicInfo 的内容:

ID | TotalPrice

 1 | 100

 2 | 150

 3 | 200

 4 | 250

这是childtabletblPayment的内容:

P_ID | ID | IsPaid | Amount

  1  |  1 |  true   | 50

  2  |  1 |  false  | 25

  3  |  2 |  false  | 100

  4  |  2 |  false  | 25

  5  |  3 |  true   | 200

这是我自己完成的:

SELECT tblBasicInfo.ID, 
    ( tblBasicInfo.TotalPrice - sum(tblPayment.Amount) ) AS [Difference]
    FROM tblBasicInfo, tblPayment 
    WHERE ( tblBasicInfo.ID = tblPayment.ID )
    GROUP BY tblBasicInfo.TotalPrice, tblPayment.IsPaid 
    HAVING ( tblPayment.IsPaid = TRUE )  --this is the criteria I talked above
    ORDER BY tblBasicInfo.ID;

这是我从上面的查询中得到的:

ID | Difference

 1 | 50
 3 | 0
 .
 .
 .

我需要得到以下结果:

ID | Difference

 1 | 50
 2 | 150     -- does not meet the criteria ( IsPayed = false )
 3 | 0
 4 | 250     -- no records in child table
 .
 .
 .

对于问题标题的不完善,我深表歉意,但我真的不知道如何描述这个问题。

(小更正 - IsPaid 而不是 IsPayed)
这没有经过测试或任何它只是希望为您指明正确的方向。
您想要使用左连接,然后检查计算 difference

中的 amount 是否为空
SELECT
    bi.ID, 
    ( bi.TotalPrice - sum(IIF(p.Amount is null,0,p.Amount)) ) AS [Difference]
    FROM tblBasicInfo bi,
        left join tblPayment p
            on p.id = bi.id
            and p.IsPaid = 1
    GROUP BY bi.ID, bi.TotalPrice
    ORDER BY bi.ID;

我在 SQL 服务器上试过这个,但是你可以在其他 RDMS 中实现同样的你可以通过不止一种方式实现这里我提出了两个解决方案我发现第一个解决方案比第二个执行得更好

SELECT ti.id,MAX(totalprice) - ISNULL(SUM(CASE WHEN is_payed = ((0)) THEN 0 ELSE amount END),0) amount
FROM tblbasicinfo ti LEFT OUTER JOIN  tblpayment tp ON ti.id = tp.p_id
GROUP BY ti.id 

--OR 

SELECT id,totalprice-ISNULL((SELECT SUM(amount) 
FROM tblpayment tp 
WHERE  ti.id = tp.p_id AND is_payed = ((1))
GROUP BY id),0) AS reconsile
 FROM tblbasicinfo ti 

CREATE TABLE tblBasicInfo (id INT IDENTITY(1,1),totalprice MONEY)

CREATE TABLE tblPayment (id INT IDENTITY(1,1), P_ID INT ,is_payed BIT,amount MONEY)

INSERT INTO tblbasicinfo

VALUES(100),(150),(200),(250)

INSERT INTO tblpayment(p_id,is_payed,amount)
VALUES(1,((1)),50),(1,((0)),25),(2,((0)),100),(2,((0)),25),(3,((1)),200)

试试这个

  select a.Id,(a.TotalPrice-payment.paid) as Difference  from tblBasicInfo a
  left join 
  (

   select sum(Amount) as paid,Id
   from 
   tblPayment
     group by Id
      where IsPaid =1)payment
    on a.Id=payment.Id