在 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 BYSUM() 我试过了,但我必须在现金和信用卡支付上都使用 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 中使用连接多个表来避免重复值的主要内容,如果未能解决你的问题,请参考以下文章

JOINing多对多表时避免SQL查询中的重复行

firebird数据库的问题么? FlameRobin 如何使用?

从连接 Firebird 读取数据时出错

通过连接多个表来更新表

Firebird isql 和 ODBC 连接的区别

Firebird字段名称转义