如何在两个表之间进行减法

时间:2017-06-20 17:54:52

标签: sql oracle

我要在列中用相同的值减去具有相同ID的值的总和,这些值具有相同的数据(这些具有相同的数据)。如果AMT列中的值只有一次只能做差异。

所以我想要AMT(表A)和AMT(表B)之间的区别,它们具有相同的ID,CRD,STN和不同的TYPE。

表A:

AMT     ID      CRD     STN     TYPE
------- ------- ------- ------- ----
22000   7123344 556677  442233  0200
22000   7123344 556677  442233  0200
22000   7123344 556677  442233  0200
11500   7132323 992211  556611  0200
10000   7132323 992211  556611  0200
35200   7199933 223344  989898  0200

表B:

AMT     ID      CRD     STN     TYPE
------- ------- ------- ------- ----
67000   7123344 556677  442233  0220
20000   7132323 992211  556611  0220
35300   7199933 223344  989898  0220

我想得到的结果:

DIFF
----
1000
-1500
100

1 个答案:

答案 0 :(得分:2)

您的样本输出与表格数据并不匹配;如果我们可以忽略100值,那么你可能想要这样的东西(在CTE中提供表数据):

with table_a (AMT, ID, CRD, STN, TYPE) as (
            select 22000, 7123344, 556677, 442233, 0200 from dual
  union all select 22000, 7123344, 556677, 442233, 0200 from dual
  union all select 22000, 7123344, 556677, 442233, 0200 from dual
  union all select 11500, 7132323, 992211, 556611, 0200 from dual
  union all select 10000, 7132323, 992211, 556611, 0200 from dual
  union all select 35200, 7178866, 223344, 989898, 0200 from dual
),
table_b (AMT, ID, CRD, STN, TYPE) as (
            select 67000, 7123344, 556677, 442233, 0220 from dual
  union all select 20000, 7132323, 992211, 556611, 0220 from dual
  union all select 67100, 7199933, 667733, 343433, 0220 from dual
)
select a.id, a.crd, a.stn, a.sum_amt, b.sum_amt, a.sum_amt - b.sum_amt as diff
from (
  select id, crd, stn, type, sum(amt) as sum_amt
  from table_a
  group by id, crd, stn, type
) a
inner join (
  select id, crd, stn, type, sum(amt) as sum_amt
  from table_b
  group by id, crd, stn, type
) b
on b.id = a.id and b.crd = a.crd and b.stn = a.stn and b.type != a.type
order by a.id, a.crd, a.stn;

        ID        CRD        STN    SUM_AMT    SUM_AMT       DIFF
---------- ---------- ---------- ---------- ---------- ----------
   7123344     556677     442233      66000      67000      -1000
   7132323     992211     556611      21500      20000       1500

子查询(内联视图)生成每个ID / CRD / STN / TYPE的总和,然后将它们连接在一起,以便可以减去等效的总和。即便如此,你的结果都是正数;如果这是你想要的那么你可以修改它来做

abs(a.sum_amt - b.sum_amt) as diff

或者你可能希望减法走另一条路,所以你得到+1000和-1500。

您可能还希望仅在表A中存在的组合有所不同:

select a.id, a.crd, a.stn, a.sum_amt, b.sum_amt,
  coalesce(a.sum_amt, 0) - coalesce(b.sum_amt, 0) as diff
from (
  select id, crd, stn, type, sum(amt) as sum_amt
  from table_a
  group by id, crd, stn, type
) a
left outer join (
  select id, crd, stn, type, sum(amt) as sum_amt
  from table_b
  group by id, crd, stn, type
) b
on b.id = a.id and b.crd = a.crd and b.stn = a.stn and b.type != a.type
order by a.id, a.crd, a.stn;

        ID        CRD        STN    SUM_AMT    SUM_AMT       DIFF
---------- ---------- ---------- ---------- ---------- ----------
   7123344     556677     442233      66000      67000      -1000
   7132323     992211     556611      21500      20000       1500
   7178866     223344     989898      35200                 35200

或表A或表B或两者中出现的组合:

select coalesce(a.id, b.id) as id, coalesce(a.crd, b.crd) as crd,
  coalesce(a.stn, b.stn) as stn, a.sum_amt, b.sum_amt,
  coalesce(a.sum_amt, 0) - coalesce(b.sum_amt, 0) as diff
from (
  select id, crd, stn, type, sum(amt) as sum_amt
  from table_a
  group by id, crd, stn, type
) a
full outer join (
  select id, crd, stn, type, sum(amt) as sum_amt
  from table_b
  group by id, crd, stn, type
) b
on b.id = a.id and b.crd = a.crd and b.stn = a.stn and b.type != a.type
order by coalesce(a.id, b.id), coalesce(a.crd, b.crd), coalesce(a.stn, b.stn);

        ID        CRD        STN    SUM_AMT    SUM_AMT       DIFF
---------- ---------- ---------- ---------- ---------- ----------
   7123344     556677     442233      66000      67000      -1000
   7132323     992211     556611      21500      20000       1500
   7178866     223344     989898      35200                 35200
   7199933     667733     343433                 67100     -67100

这些使用左外连接或全外连接,并添加coalesce()调用来处理在一个内联视图或另一个内联视图中不存在的数据。

使用修改后的数据,并反转计算以获得所需的符号,这将获得您期望的结果:

with table_a (AMT, ID, CRD, STN, TYPE) as (
            select 22000, 7123344, 556677, 442233, 0200 from dual
  union all select 22000, 7123344, 556677, 442233, 0200 from dual
  union all select 22000, 7123344, 556677, 442233, 0200 from dual
  union all select 11500, 7132323, 992211, 556611, 0200 from dual
  union all select 10000, 7132323, 992211, 556611, 0200 from dual
  union all select 35200, 7199933, 223344, 989898, 0200 from dual
),
table_b (AMT, ID, CRD, STN, TYPE) as (
            select 67000, 7123344, 556677, 442233, 0220 from dual
  union all select 20000, 7132323, 992211, 556611, 0220 from dual
  union all select 35300, 7199933, 223344, 989898, 0220 from dual
)
select a.id, a.crd, a.stn, a.sum_amt, b.sum_amt, b.sum_amt - a.sum_amt as diff
from (
  select id, crd, stn, type, sum(amt) as sum_amt
  from table_a
  group by id, crd, stn, type
) a
inner join (
  select id, crd, stn, type, sum(amt) as sum_amt
  from table_b
  group by id, crd, stn, type
) b
on b.id = a.id and b.crd = a.crd and b.stn = a.stn and b.type != a.type
order by a.id, a.crd, a.stn;

        ID        CRD        STN    SUM_AMT    SUM_AMT       DIFF
---------- ---------- ---------- ---------- ---------- ----------
   7123344     556677     442233      66000      67000       1000
   7132323     992211     556611      21500      20000      -1500
   7199933     223344     989898      35200      35300        100