SQL在同一行

时间:2015-07-07 09:59:14

标签: sql oracle oracle11g

我有一个包含1条记录的表,然后绑定到辅助表,该表可以包含无匹配,1匹配或2匹配。

我需要获取相应的记录并将它们显示在同一行中,如果我只有1个匹配或没有匹配可以轻松使用left join,但是,因为我可以得到2个匹配,它会产生2条记录。

1场比赛的示例:

Select T1.ID, T1.Person1, T2.Owner
From T1
Left Join T2
  ON T1.ID = T2.MatchID

输出

ID   Person1  Owner1 
----------------------
1    John     Frank

2场比赛的示例:

Select T1.ID, T1.Person1, T2.Owner
From T1
Left Join T2
  ON T1.ID = T2.MatchID

输出

ID   Person1  Owner 
----------------------
1    John     Frank
1    John     Peter

有没有办法可以制定我的选择,以便我的输出反映以下内容当我有2场比赛时:

ID   Person1  Owner1   Owner2
-------------------------------
1    John     Frank     Peter

我稍微探讨了Oracle Pivots,但无法找到一种方法来完成这项工作。还研究了在获取匹配项时使用left joinMIN()在同一个表上使用MAX()的可能性,但我只能看到自己将此作为“无其他选项”方案。

有什么建议吗?

**编辑**

@ughai - 使用CTE确实在某种程度上解决了这个问题,但是在尝试检索所有记录时,从这个公共表派生的详细信息没有在LEFT JOIN上显示任何记录,除非我指定“MatchID” (CASE_MBR_KEY)值,意味着通过删除“where”子句,我的外连接不会产生任何记录,即使CTE数据中存在CASE_MBR_KEY值。

WITH CTE AS
(
SELECT TEMP.BEAS_KEY, 
       TEMP.CASE_MBR_KEY,
       TEMP.FULLNAME,
       TEMP.BIRTHDT,
       TEMP.LINE1,
       TEMP.LINE2,
       TEMP.LINE3,
       TEMP.CITY,
       TEMP.STATE,
       TEMP.POSTCD,
       ROW_NUMBER() 
  OVER(ORDER BY TEMP.BEAS_KEY) R
  FROM TMP_BEN_ASSIGNEES TEMP
  --WHERE TEMP.CASE_MBR_KEY = 4117398
)

原因是因为ROW_NUMBER值,给定记录的数量不一定是1或2,所以我尝试了以下,但得到 ORA-01799:列可能不是外连接到子查询

--// BEN ASSIGNEE 1
LEFT JOIN CTE BASS1
  ON BASS1.CASE_MBR_KEY = C.CASE_MBR_KEY  
 AND BASS1.R IN (SELECT min(R) FROM CTE A WHERE A.CASE_MBR_KEY = C.CASE_MBR_KEY)
--// END BA1 

--// BEN ASSIGNEE 2
LEFT JOIN CTE BASS2
  ON BASS2.CASE_MBR_KEY = C.CASE_MBR_KEY  
 AND BASS2.R IN (SELECT MAX(R) FROM CTE B WHERE B.CASE_MBR_KEY = C.CASE_MBR_KEY)
--// END BA2 

**编辑2 **

通过将Row number子句移动到查询的“Where”部分而不是JOIN子句中来解决上述问题。似乎现在正在工作。

2 个答案:

答案 0 :(得分:1)

您可以将CTEROW_NUMBER()同时使用2 LEFT JOINPIVOT使用WITH CTE as ( SELECT MatchID,Owner,ROW_NUMBER()OVER(ORDER BY Owner) r FROM t2 ) select T1.ID, T1.Person, t2.Owner as Owner1, t3.Owner as Owner2 FROM T1 LEFT JOIN CTE T2 ON T1.ID = T2.MatchID AND T2.r = 1 LEFT JOIN CTE T3 ON T1.id = T3.MatchID AND T3.r = 2;

SQL Fiddle

使用多个左连接查询

WITH CTE as 
(
  SELECT MatchID,Owner,ROW_NUMBER()OVER(ORDER BY Owner) R FROM t2
)
SELECT ID, Person,O1,O2
FROM T1
LEFT JOIN CTE T2
ON  T1.ID = T2.MatchID
PIVOT(MAX(Owner) FOR R IN (1 as O1,2 as O2));

使用PIVOT查询

ID  PERSON  OWNER1  OWNER2
1   John    Maxwell Peter

<强>输出

UNIONs

答案 1 :(得分:1)

如果你知道最多有两个匹配,你也可以使用聚合:

Select T1.ID, T1.Person1,
       MIN(T2.Owner) as Owner1,
       (CASE WHEN MIN(t2.Owner) <> MAX(t2.Owner) THEN MAX(t2.Owner) END) as Owner2
From T1 Left Join
     T2
     on T1.ID = T2.MatchID
Group By t1.ID, t1.Person1;