查询两个表中的数据并仅选择已修改的记录

时间:2018-06-06 10:14:53

标签: sql

我要做的是:

我有一个TableA包含所有记录。

account | name | items | amount
0017532      A       3     1500
0034524      B       5      700
7772618      C       7      300
5467382      D       2      450
7772618      C       6     2200

另一个TableB包含:

account | name | items | amount
0034524      B       2      200
5467382      D       1       50
6483232      E       1       25

所需的查询结果是:

account | name | items | amount
0017532      A       3     1500
0034524      B       3      500
7772618      C       7      300
5467382      D       1      400
6483232      E       1       25
7772618      C       6     2200

如果有表B中的记录那么 TableA.item - TableB.item和TableB.amount - TableB.amount

结果应该包含表A中的所有记录和上面减法的结果。

我加入TableA和TableB并执行减号操作,但结果仅返回与TableB中的记录数匹配的记录

account | name | items | amount
0034524      B       3      500
5467382      D       1      400
6483232      E       1       25

当我用查询TableA尝试UNION上面的减法查询时,结果发现两个表的记录全部列出:

account | name | items | amount
0017532      A       3     1500
0034524      B       5      700
0034524      B       3      500
7772618      C       7      300
5467382      D       2      450
5467382      D       1      400
7772618      C       6     2200
6483232      E       1       25

如果TableA中存在'account'和'name',我正试图找到一种只从TableB中选择记录的方法。

2 个答案:

答案 0 :(得分:0)

我认为获得所需内容的最简单方法是使用left joinunion all

select a.account, a.name,
       (a.items - coalesce(b.items, 0)) as items,
       (a.amount - coalesce(b.amount, 0)) as amount
from a left join
     b
     on a.account = b.account
union all
select b.account, b.name, b.items, b.amount
from b
where not exists (select 1
                  from a
                  where a.account = b.account
                 );

您也可以使用full join,但逻辑很麻烦,因为来自b的数据有迹象:

select coalesce(a.account, b.account) as account,
       coalesce(a.name, b.name) as name,
       (case when a.account is null then b.items
             else a.items - coalesce(b.items, 0)
        end) as items,
       (case when a.account is null then b.amount
             else a.amount - coalesce(b.amount, 0)
        end) as items
from a full join
     b
     on a.account = b.account;

答案 1 :(得分:0)

如果每个表中的帐户不唯一?
那么你可能只想将B减去A一次。

在这种情况下,您还可以在帐户和计算的row_number上完全加入它们。

假设您的数据库支持诸如row_number 之类的窗口函数 Btw,i.m.h.o。那些预期的结果似乎误导了我

示例数据

create table TableA (account char(7), name char(1), items integer, amount integer);
create table TableB (account char(7), name char(1), items integer, amount integer);

insert into TableA (account, name, items, amount) values
('1111111', 'A', 10, 100),
('2222222', 'B', 20, 200),
('3333333', 'C', 30, 310),
('3333333', 'C', 30, 320),
('4444444', 'D', 40, 400),
('6666666', 'F', 60, 610),
('6666666', 'F', 60, 620);

insert into TableB (account, name, items, amount) values
('2222222', 'B', 10, 100),
('4444444', 'D', 10, 100),
('5555555', 'E', 10, 100),
('6666666', 'F', 10, 100);

<强>查询:

select 
coalesce(a.account, b.account) as Account, 
coalesce(a.name, b.name) as Name, 
coalesce(case when a.items is not null and b.items is not null then a.items - b.items end, a.items, b.items) as Items,
coalesce(case when a.amount is not null and b.amount is not null then a.amount - b.amount end, a.amount, b.amount) as Amount
from 
(
   select account, name, items, amount,
    row_number() over (partition by account order by amount) as rn
   from TableA
) as a
full join
(
   select account, name, items, amount,
    row_number() over (partition by account order by amount) as rn
   from TableB
) as b on (B.account = A.account and B.rn = A.rn)
order by Account;