在JOINing时防止双/三重SUMing

时间:2012-08-03 16:38:10

标签: sql sql-server sql-server-2008 tsql

我正在加入两个表:accn_demographicsaccn_payments。这两个表之间的关系为one to manyaccn_demographics.accn_id

之间的accn_payments.accn_id

我的问题是,当我总结PAID_AMT和COPAY_AMT时,我得到的是双倍/三倍/四倍数我应该得到的数字。

我的join条件是否存在明显问题?

select sum(p.paid_amt) as SumPaidAmount
    , sum(p.copay_amt) as SumCoPay
    , p.pmt_date
    , d.load_Date
    , p.ACCN_ID
from  accn_payments p
join 
(
    select distinct load_date, accn_id 
    from accn_demographics
) d
    on p.ACCN_ID=d.ACCN_ID
where p.POSTED='Y'
    and p.pmt_date between '20120701' and '20120731'
group by p.pmt_date, d.load_Date,p.ACCN_ID
order by 3 desc

非常感谢你的指导。

3 个答案:

答案 0 :(得分:1)

我唯一可以看到(select distinct load_date, accn_id from accn_demographics)可能会返回多个匹配项。查看您的数据并运行单独的查询

select distinct load_date, accn_id from accn_demographics WHERE accn_id=SomeID

其中SomeID是返回double / triple值的结果帐户之一。这应该能够找出你的问题。

答案 1 :(得分:1)

您需要在子查询中进行求和:

select sum(p.SumPaidAmount) as SumPaidAmount, sum(p.SumCoPay) as SumCoPay,
       p.pmt_date, d.load_Date, p.ACCN_ID
from  (select accn_id, p.pmt_date, sum(paid_amt) as SumPaidAmt,
              sum(copay_amt) as SumCoPay
       from accn_payments p
       where p.POSTED='Y' and
             p.pmt_date between '20120701' and '20120731'
       group by accn_id, pmt_date
      ) p join
      (select distinct load_date, accn_id from accn_demographics) d
      on p.ACCN_ID=d.ACCN_ID
group by p.pmt_date, d.load_Date,p.ACCN_ID
order by 3 desc

问题:你真的打算让pmt_date进入最终结果吗?看起来您想要从外部SELECT和子查询中删除它。

答案 2 :(得分:1)

是的,但对初学者来说并不那么明显。会发生的情况是,对于每个accn_payments记录,您只匹配accn_id,这意味着如果accn_demographics中有特定accn_id的多条记录,那么您由于加入,将获得重复的accn_payment条记录。 accn_demographics上还有另一个限制字段可以加入付款吗?

最终,想一想:

accn_payments(p):

accn_id    |    paid_amt    |    copay_amt    |  ...
----------------------------------------------------
1          |    100.00      |    20.00        |  ...

accn_demographics(d):

accn_id    |    load_date   |    ...
------------------------------------
1          |    2012/01/01  |    ...
1          |    2012/03/05  |    ...
1          |    2012/06/23  |    ...

加入后,您的结果将如下所示:

p.accn_id | p.paid_amt | p.copay_amt | p... | d.accn_id | d.load_date | d...
----------------------------------------------------------------------------
1         | 100.00     | 20.00       | .... | 1         | 2012/01/01  | ....
1         | 100.00     | 20.00       | .... | 1         | 2012/03/05  | ....
1         | 100.00     | 20.00       | .... | 1         | 2012/06/21  | ....

如您所见,每个匹配的accn_payments记录都会复制accn_demographics中的同一行,因为您只指定了accn_id列作为连接条件。它不能进一步限制结果,因此数据库引擎说“嘿,看,这p条记录与所有这些d记录匹配,这一定是他要求的!”显然不是预期的,就像你对p.paid_amtp.copay_amt求和时,它会为所有行执行求和(即使它们是重复的)。

最终,看看您是否可以进一步限制accn_demographics的加入条件(可能在某个日期),这样就可以限制加入期间重复付款记录的数量。