2016-11-07 7 views
-2

複数のテーブルをクエリしたいが、一意のレコードのみを返す。Oracle:複数のテーブルから異なるレコードをクエリする方法

私の現在のクエリ:

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 
+0

'c_inv'データがありません。 – Aleksej

答えて

1

ないこの出力が便利ですかどうかはわかりますが、それを得るためには、あなたが参加し、UNIONをする必要はありません。 (注 - 個別にそれを追加する必要はありませんので、UNIONDISTINCT操作を行います。)

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

を結果はあなたが示した順序で、または任意の他の順序で来るかもしれません。特定の注文が必要な場合は、明示的にORDER BY ....を使用してください。

0

c_code +プロジェクトに対してあるp_code間の1対1のマッピングがある場合、次のクエリは動作します:

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 
0

あなたは、行の数を減らしたいです。これは、2つのアプローチのうちの1つを示唆しています: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では、文字列の位置は "0"ではなく "1"から開始するので、substr()呼び出しを変更しました。

+0

' distinct'は行数を減らします(OPの出力と同じように見えます)。そして、 'distinct'は集合理論的操作(' union all'を除く - これは集合理論的操作ではありません)によって包含されます。 – mathguy

関連する問題