2016-05-21 34 views
1

多対多の関係を持つ2つのテーブルがあります。私はそれらに参加し、一致したレコードを取得する必要があります。SQLで多対多の関係を持つ2つのテーブルに結合する

Table 1 

Column1 | column 2| column 3| 
1|p1|1.0 
1|p1|1.1 
1|p1|1.2 

Table 2 

Column1 | column 2| column 3| 
1|p1|2.0 
1|p1|2.1 
1|p1|2.2 

私はcolumn1のとcolumn2のマッチングを意味し、[編集] 1 COLUMN3のために両方の列から

を値を示す

1|p1|1.0|2.0 
1|p1|1.1|2.1 
1|p1|1.2|2.2 

として今、私は結果が欲しい: 私は1つの問題があるMT0クエリをしようとした後、 。私は非常に彼の答えに満足しているが、まだいくつかの変更が行われる必要があります。

Table 1 

Column1 | column 2| column 3| 
1|p1|1.0 
1|p1|1.1 
1|p1|1.2 

Table 2 

Column1 | column 2| column 3| 
1|p1|1.0 
1|p1|1.2 

今、私は

1|p1|1.0|1.0 
1|p1|1.1|NULL 
1|p1|1.2|1.2 

として結果をしたいが、してください

1|p1|1.0|1.0 
1|p1|1.1|1.2 
1|p1|1.2|NULL 

として、私は取得していますこれについて助けてください

+0

は、明確にするために - あなたはcolumn1の、column2のに係る継手にしたい、といくつかの順序は、(例えば、表1に(1、P1)の最初の行は、表2に(1、P1)の最初の行にマッチし、 table1の2番目の行とtable2の2番目の行などが一致します)。 – Mureinik

+0

はい。私はそのようにしたい –

+0

'column3'の値が' table1'では '1.0,1.1,1.2'、' table2'では '2.0,2.2 'でないと結果はどうなるでしょうか?また、小数点の値の類似性を持つ数値は常に数値であるか、これは序数の位置の例としてのみ使用されており、数値は非数値または大きく異なる可能性がありますか? – MT0

答えて

2

を使用すると、各パーティションの行の異なる数を持っているなら、あなたが行うことができます:

Oracleのセットアップ

CREATE TABLE table1 (col1, col2, col3) AS 
SELECT 1, 'P1', '1.0' FROM DUAL UNION ALL 
SELECT 1, 'P1', '1.1' FROM DUAL UNION ALL 
SELECT 1, 'P1', '1.2' FROM DUAL UNION ALL 
SELECT 1, 'P2', '1.0' FROM DUAL UNION ALL 
SELECT 1, 'P2', '1.2' FROM DUAL UNION ALL 
SELECT 2, 'P1', '1.0' FROM DUAL; 

CREATE TABLE table2 (col1, col2, col3) AS 
SELECT 1, 'P1', '2.0' FROM DUAL UNION ALL 
SELECT 1, 'P1', '2.1' FROM DUAL UNION ALL 
SELECT 1, 'P1', '2.2' FROM DUAL UNION ALL 
SELECT 1, 'P2', '2.1' FROM DUAL UNION ALL 
SELECT 2, 'P1', '2.0' FROM DUAL UNION ALL 
SELECT 2, 'P1', '2.1' FROM DUAL; 

クエリ

SELECT COALESCE(t1.col1, t2.col1) AS col1, 
     COALESCE(t1.col2, t2.col2) AS col2, 
     t1.col3 AS t1col3, 
     t2.col3 AS t2col3 
FROM (
     SELECT t.*, 
       ROW_NUMBER() OVER (PARTITION BY col1, col2 
            ORDER BY col3) AS rn 
     FROM table1 t 
     ) t1 
     FULL OUTER JOIN 
     (
     SELECT t.*, 
       ROW_NUMBER() OVER (PARTITION BY col1, col2 
            ORDER BY col3) AS rn 
     FROM table2 t 
     ) t2 
     ON (t1.col1 = t2.col1 AND t1.col2 = t2.col2 AND t1.RN = t2.rn) 
ORDER BY col1, col2, t1col3 NULLS LAST, t2col3 NULLS LAST; 

出力

 COL1 COL2 T1COL3 T2COL3 
---------- ---- ------ ------ 
     1 P1 1.0 2.0  
     1 P1 1.1 2.1  
     1 P1 1.2 2.2  
     1 P2 1.0 2.1  
     1 P2 1.2   
     2 P1 1.0 2.0  
     2 P1   2.1  
+0

ありがとうMT0、私は助けをurとの答えを得た。しかし、唯一の問題は1 | p1 | 1 1 | p1 | 1 | p1 | 3であり、別のテーブルは1 | p1 | 1 | p1 | 3の値をとっているので、1 | p1 | 1 | 1 1 | p1 | 1 | 3 1 | p1 | 3 | nullを取得するには1 | p1 | 1 | 1 | p1 | 1 | null 1 | p1 | 3 | 3 –

+0

私のコメントを読むのは難しいですが、より良い方法で書くことができない –

0

を使用して番号付きの計算カラムを追加することができます窓関数と参加していることを使用します。

SELECT t1.column1, t2.column2, t1.column3, t2.column3 
FROM (SELECT column1, column2, column3, 
       ROW_NUMBER() OVER (PARTITION BY column1, column2 
            ORDER BY  column3) AS rn 
     FROM table1) t1 
JOIN (SELECT column1, column2, column3, 
       ROW_NUMBER() OVER (PARTITION BY column1, column2 
            ORDER BY  column3) AS rn 
     FROM table2) t2 ON t1.column1 = t2.column1 AND 
          t1.column2 = t2.column2 AND 
          t1.rn  = t2.rn 
0

1つの以上の列のみを表2に同じことを行うと、参加左のキーとしてそれを使用

alter table 1 
add column1 char(100) 
alter table 2 
add column2 char(100) 
so table 1 
Column1 | column 2| column 3|column4 
1|p1|1.0      
1|p1|1.1 
1|p1|1.2 
update table table1 
set column4 = left(column1,4) 

のように両方のテーブルに一致するIDを持つ作成します。

0

以下を試してください。

create table tab1(Col1 int,col2 varchar(10), col3 varchar(10)) 

insert into tab1 
values(1,'p1','1.0'), 
(1,'p1','1.1'), 
(1,'p1','1.2') 

create table tab2(Col1 int,col2 varchar(10), col3 varchar(10)) 

insert into tab2 
values(1,'p1','2.0'), 
(1,'p1','2.1'), 
(1,'p1','2.2') 

SELECT a.col1,a.col2,a.col3,b.col3 
FROM 
(
    select 
    *,ROW_NUMBER() over(order by col1) as rownum 
    from tab1 
)a 
inner join 
(
    select *,ROW_NUMBER() over(order by col1) as rownum 
    from tab2 
)b ON a.rownum = b.rownum and a.Col1 = b.Col1 
関連する問題