Oracle:如何查询多个表中的不同记录?

时间:2016-11-07 11:10:02

标签: sql oracle join duplicates left-join

我想查询多个表但只返回唯一记录。

我当前的查询:

select 
    a.*, 
    b.*, 
    c.*
from c_inv a 
    inner join p_master b 
        on a.c_code = b.c_code 
            and a.p_code = b.p_code
    left join c_proj c 
        on b.c_code = c.c_code 
            and b.p_code = c.p_code
where a.c_code = 'AA'
    and a.d_type = 'IN' 
    and a.s_type = substr('OI',0,2)
    and a.g_flag = 'N'     
    and a.startdate <= trunc(sysdate)     
    and nvl(a.enddate, trunc(sysdate)) >= trunc(sysdate)
order by a.p_code

数据样本

p_master
c_code  p_code
AA      Test01          
AA      Test02
AA      Test03

c_proj
c_code  p_code      proj    startdate   enddate
AA      Test99      clound  01/10/2016  31/10/2016
AA      Test99      clound  01/09/2016  30/09/2016
AA      Test99      clound  01/08/2016  31/08/2016

我目前的结果:

c_code  p_code
AA      Test01          
AA      Test02
AA      Test03
AA      Test99
AA      Test99
AA      Test99

目标结果:

c_code  p_code      proj
AA      Test01      null    
AA      Test02      null
AA      Test03      null
AA      Test99      clound

3 个答案:

答案 0 :(得分:1)

不确定此输出是如何有用的,但要获得它,您需要UNION,而不是连接。 (注意 - UNION也执行DISTINCT操作,因此您无需单独添加。)

select p_code, c_code, null as proj from p_master
union
select p_code, c_code,         proj from c_proj

结果可能按照您显示的顺序或任何其他顺序排列;如果您需要特定订单,请使用显式ORDER BY ....

答案 1 :(得分:0)

如果c_code + p_code与项目之间存在一对一的映射,则后续查询将起作用:

select  a.c_code,a.p_code,max(proj)
from    c_inv a 
inner join p_master b 
    on  a.c_code = b.c_code 
    and a.p_code = b.p_code
left join c_proj c 
    on  b.c_code = c.c_code 
    and b.p_code = c.p_code
where   a.c_code = 'AA'
    and a.d_type = 'IN' 
    and a.s_type = substr('OI',0,2)
    and a.g_flag = 'N'     
    and a.startdate <= trunc(sysdate)     
    and nvl(a.enddate, trunc(sysdate)) >= trunc(sysdate)
group   by a.c_code,a.p_code    
order   by a.p_code

答案 2 :(得分:0)

您想减少行数。这表明了两种方法之一:聚合或使用窗口函数,如row_number()。聚合方法如下:

select i.c_code, i.p_code, max(p.proj) as proj
from c_inv i inner join
     p_master m
     on i.c_code = m.c_code and i.p_code = m.p_code left join
     c_proj p
     on m.c_code = p.c_code and m.p_code = p.p_code
where i.c_code = 'AA' and
      i.d_type = 'IN' and
      i.s_type = substr('OI', 1, 2) and
      i.g_flag = 'N' and
      i.startdate <= trunc(sysdate) and    
      nvl(i.enddate, trunc(sysdate)) >= trunc(sysdate)
group by i.c_code, i.p_code;

我将表别名更改为表名的缩写。这样可以更轻松地按照查询进行操作。

此外,在SQL中,字符串中的位置始于&#34; 1&#34;而不是&#34; 0&#34;,所以我改变了substr()电话。