我要在列中用相同的值减去具有相同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
答案 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