【问题标题】:Oracle: How to query distinct records from multiple tables?Oracle:如何从多个表中查询不同的记录?
【发布时间】:2017-03-20 17:05:33
【问题描述】:

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

我当前的查询:

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

【问题讨论】:

  • 您似乎缺少c_inv数据

标签: sql oracle join duplicates left-join


【解决方案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 ....

【讨论】:

    【解决方案2】:

    如果 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
    

    【讨论】:

      【解决方案3】:

      您想减少行数。这表明了以下两种方法之一:聚合或使用窗口函数,例如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 中,字符串中的位置从“1”而不是“0”开始,所以我更改了substr() 调用。

      【讨论】:

      • distinct 还减少了行数(并且似乎与 OP 的输出相匹配)。并且distinct 包含在集合论运算中(union all 除外 - 无论如何这不是集合论运算)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-28
      • 1970-01-01
      相关资源
      最近更新 更多