用 SUM 从 parent table 中减去值(child table 中的值)
Subtracting value from parent table with SUM(value from child table)
我有 2 个 table,tblBasicInfo
和 tblPayment
。
关系是一对多,其中tblBasicInfo
在1方,tblPayment
在many
方。
关系是可选的,这就是问题所在。
我需要用 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
我有 2 个 table,tblBasicInfo
和 tblPayment
。
关系是一对多,其中tblBasicInfo
在1方,tblPayment
在many
方。
关系是可选的,这就是问题所在。
我需要用 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
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