2016-08-24 44 views
0

に参加:SQL左は、私は1つの表を持っている3つのテーブル

Contacts (ID integer, Name text, ATT_ID integer) 

私の表は、これらの値で満たされている:

(1, 'Alice', 1) 
(2, 'Bob', 1) 
(3, 'Carol', 1) 
(4, 'Dave', 4) 
(5, 'Eve', 4) 
(6, 'Frank', 6) 

目標はペアATT_IDでこれらの連絡先IDに参加することです。

これが私の現在のSQL-コード:

SELECT t1.ID as ID, t1.Name , tt.Name , tt2.Name 
FROM Contacts as t1 

LEFT JOIN (
SELECT MIN(t2.ID), t2.Name, t2.ATT_ID FROM Contacts as t2 
WHERE t2.ID <> t2.ATT_ID) 
AS tt ON t1.ID = tt.ATT_ID 

LEFT JOIN (
SELECT MAX(t3.ID), t3.Name, t3.ATT_ID FROM Contacts as t3 
WHERE t3.ID <> t3.ATT_ID) 
AS tt2 ON t1.ID = tt2.ATT_ID 

WHERE t1.ID = t1.ATT_ID; 

と私の結果は次のとおりです。

Alice | Bob | null 
Dave | null | Eve 
Frank | null | null 

しかし、所望の結果は次のようになります。

Alice | Bob | Carol 
Dave | Eve | null 
Frank | null | null 

どのようにすることができますこれを達成する?あなたのRDBMSを仮定

+2

どのRDBMS? MySQL、SQL Server Oracleその他 – xQbert

+0

RDBMS:SQL Oracle –

答えて

0

は、窓関数をサポートしています...

これは、各サブグループのための行番号を生成し、唯一最小行数を表示することによって達成することができます。

これは、各グループに3を超えないことを前提としています。

以下はORACLE固有のものですが、MS SQL、Postgresql、およびDB2で動作する必要があります。ウィンドウ関数はサポートされていないので、MySQLでは動作しません。

ビルド済みのwithブロックは、ORACLEでのみ機能することに注意してください。

With contacts (ID, Name, ATT_ID) as ( 
Select 1, 'Alice', 1 from dual union all 
Select 2, 'Bob', 1 from dual union all 
Select 3, 'Carol', 1 from dual union all 
Select 4, 'Dave', 4 from dual union all 
Select 5, 'Eve', 4 from dual union all 
Select 6, 'Frank', 6 from dual) 

--FROM HERE ON should work if window functions supported. 

Select * from (
Select T1.Name N1, T2.Name N2, T3.Name N3, Row_Number() Over (partition by T1.ATT_ID order by T1.ID) rn 
FROM Contacts T1 
LEFT JOIN Contacts T2 
on T1.ATT_ID = T2.ATT_ID 
and T1.ID < T2.ID 
LEFT JOIN contacts T3 
on T2.ATT_ID = T3.ATT_ID 
and T2.ID < T3.ID 
and T1.ID < T3.ID) B 
WHERE RN =1 

enter image description here

関連する問題