SQL:这不是一个简单的左右联接问题

时间:2019-04-11 20:35:56

标签: sql

我有两个表,每个表都有2列(名称[字符串],值[整数]) 我试图将两者结合起来以显示每个名称的sum(value)之间的差异。例如

表1(t1):

N1  2
N1  3
N2  4
N3  5

表(t2):

N1  1
N2  1
N2  1

结果应如下所示:

N1 4  (5-1)
N2 2  (4-2)
N3 5  (5-0)  

如果其中一个表中缺少N,我们想假设为0

如果两个表中都存在名称,我只知道如何进行联接,但是如果其中一个表中都缺少名称,我不知道如何处理将空结果替换为0的情况。

我当前的查询:

select t1.name, t2.name, t1.Sum-t2.Sum as "Diff"
from (select t1.name, sum(t1.value) as Sum from t1 group by t1.name) t1 
inner join
(select t2.name, sum(t2.value) as Sum from t2 group by t2.name) t2 
on t1.name = t2.name

结果忽略N3,因为t1中缺少N3。

谢谢

4 个答案:

答案 0 :(得分:1)

您可以使用CTE(公用表表达式)聚合两个表,然后使用FULL OUTER JOIN将它们联接起来,如下所示:

with
l as (
  select name, sum(value) as total
  from table1
  group by name
),
r as (
  select name, sum(value) as total
  from table2
  group by name
)
select
  coalesce(l.name, r.name) as name,
  coalesce(l.total, 0) - coalesce(r.total, 0) as difference
from l
full outer join r on l.name = r.name
order by coalesce(l.name, r.name)

答案 1 :(得分:1)

使用FULL OUTER JOIN和ISNULL

SELECT ISNULL(x.name, y.name) as Name,
       ISNULL(x.sumValues, 0) - ISNULL(y.sumValues, 0) as ValueDiff
FROM
(SELECT name, SUM(value) AS sumValues FROM t1 GROUP BY name) x
    FULL OUTER JOIN
    (SELECT name, SUM(value) AS sumValues FROM t2 GROUP BY name) y
        ON x.name = y.name;

答案 2 :(得分:0)

一个非常简单的方法是union all和聚合:

select name, sum(value)
from ((select name, value
       from t1
      ) union all
      (select name, -value
       from t2
      )
     ) t
group by name;

join有点混乱,因为除非非常小心,否则它可能导致值重复和丢失。

答案 3 :(得分:0)

这将起作用:

输入:

create table t1 (name varchar(20),value number);
create table t2 (name varchar(20),value number);
//do inserts

select name1,nvl(sum1-sum2,sum1) from(select sum(t1.value) as sum1,t1.name name1 from t1 group by t1.name)
,(select sum(t2.value) as sum2,t2.name name2 from t2 group by t2.name) where name1=name2(+);

输出:

N1  4
N2  2
N3  5