在 Firebird 中使用连接多个表来避免重复值
Posted
技术标签:
【中文标题】在 Firebird 中使用连接多个表来避免重复值【英文标题】:Avoid duplicate values using join with multiple tables in Firebird 【发布时间】:2021-12-28 12:22:08 【问题描述】:我有 3 张桌子
付款
PaymntID | Date | Amount |
---|---|---|
1 | Ago.2021 | 500 |
2 | Sep.2021 | 1200 |
3 | Oct.2021 | 600 |
现金支付
PaymntID | Amount |
---|---|
1 | 500 |
2 | 400 |
3 | 200 |
信用卡支付
PaymntID | Amount | CreditCard |
---|---|---|
2 | 450 | Visa |
2 | 350 | MC |
3 | 400 | Visa |
我需要获取 PaymentID、日期、现金支付金额和信用卡支付金额,但通过以下查询,我得到了重复项。
请注意,我可以在一次付款中使用两张不同的信用卡,但我也可以在一次付款中使用两种不同的“现金付款”。
查询:
select
PA.DATE AS PaymntDate,
PA.PaymntID AS PaymntID,
CP.amount AS CashAmount,
CCP.amount AS CreditAmount,
from Payments PA
LEFT join CashPayments CP on PA.PaymntID = CP.PaymntID
LEFT join CreditCardPayments CCP on PA.PaymntID = CCP.PaymntID
我得到以下结果:
结果
PaymntID | PaymntDate | CashAmount | CreditAmount |
---|---|---|---|
1 | Ago.2021 | 500 | null |
2 | Sep.2021 | 400 | 450 |
2 | Sep.2021 | 400 | 350 |
3 | Oct.2021 | 200 | 400 |
所以在这种情况下,paymntid 2 中的现金支付是重复的。我需要的是下表:
结果
PaymntID | PaymntDate | CashAmount | CreditAmount |
---|---|---|---|
1 | Ago.2021 | 500 | null |
2 | Sep.2021 | 400 | 800 |
3 | Oct.2021 | 200 | 400 |
【问题讨论】:
提示:GROUP BY
,SUM()
。
我试过了,但我必须在现金和信用卡支付上都使用 sum() 函数。当我尝试该选项时,我在结果表中得到“800”作为现金金额(id 2)。
派生表(子查询)中的GROUP BY,之前加入!
【参考方案1】:
您需要在加入之前汇总每个 ID 的值。可能最简洁的方法是使用 CTE,然后将每个外部连接到您的 payments 表,如下所示:
with cp as (
select paymentId, Sum(Amount) Amount
from CashPayments
group by PaymentId
), ccp as (
select paymentId, Sum(Amount) QAmount
from CreditCardPayments
group by PaymentId
)
select p.PaymentId, p.Date,
Coalesce(cp.Amount,0) CashAmount,
Coalesce(ccp.Amount,0) CreditAmount
from Payments p
left join cp on cp.PaymentId = p.PaymentId
left join ccp on ccp.PaymentId = p.PaymentId
【讨论】:
非常感谢,完美运行!只是一个问题,如果我需要添加一个条件来从其中一个表中获取数据。即 cp.sellerid = 'abc' 我应该在哪里写?这里:sql with cp as ( select paymentId, Sum(Amount) Amount from CashPayments where CashPayments.sellerid = 'abc' group by PaymentId ),
或这里:sql left join cp on cp.PaymentId = p.PaymentId and cp.sellerid = 'abc'
再次感谢!
您的问题中没有SellerId
很难说,这取决于您是否正在调整特定的SellerId
或想要包含所有内容,因此您将其包含在CTE 中并包含在group by
和可能的 join
标准 - 取决于数据。
对不起,在真实的数据库中,cashpayments 表有更多列,所以问题是如果我只需要在满足特定条件的情况下获取数据,比如 Sellerid = 'abc'。我将该子句包含在子查询中作为“其中 cashpayments.sellerid = 'abc' 并且工作。现在我正在检查数据,看看我是否得到了考虑到该标准的正确金额。
如果您无法成功地将其应用到您的实际场景中,那么请务必将其作为一个新问题提出,并附上额外的信息和标准。以上是关于在 Firebird 中使用连接多个表来避免重复值的主要内容,如果未能解决你的问题,请参考以下文章