使用SUM从子表中减去值(子表中的值)

时间:2015-02-10 04:05:26

标签: sql ms-access-2007

我有2个表,tblBasicInfotblPayment

关系是1对多,其中tblBasicInfo位于1侧,tblPayment位于many侧。

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

我需要从父表中减去某些字段的值,并使用符合特定条件的子表中某些字段的总和。

如果子表中没有符合条件的记录,则应使用零(data from parent table - 0)表示。

我道歉,如果这不是很清楚,英语不是我的母语,我没有足够的经验知道如何正确描述问题。

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

我们将从表架构开始:

tblBasicInfo: #ID, TotalPrice (double)

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

以下是父表tblBasicInfo的内容:

ID | TotalPrice

 1 | 100

 2 | 150

 3 | 200

 4 | 250

以下是子表tblPayment的内容:

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
 .
 .
 .

我为问题的不完美标题道歉,但我真的不知道如何描述这个问题。

3 个答案:

答案 0 :(得分:1)

我在SQL Server上尝试了这个,但你可以在其他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 

enter image description here

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)

答案 1 :(得分:1)

试试这个

  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

答案 2 :(得分:0)

(小修正 - IsPaid而不是IsPayed)
这没有经过测试,或者只是希望将您指向正确的方向 您想使用左连接,然后在计算difference

时检查金额是否为空
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;