Oracle SQL中的自联接-根据1个相同的列和1个不同的列选择行

时间:2018-07-10 15:30:36

标签: sql oracle oracle11g self-join

这可能不是我需要的自我加入,但我在解决这个问题上遇到了困难,希望有人可以帮助我。

样本数据:

Row   Code   ReservationID   ClientID EmployeeID
1     T            123          7777     John 
2     T            456          2020     John
3     P            456          2020     John
4     P            999          3100     Steve
5     P            876          3100     Steve
6     T            333          2424     John
7     P            333          2424     Lynda

所需的输出:

Row   Code   ReservationID   ClientID EmployeeID
2     T            456          2020     John
3     P            456          2020     John
6     T            333          2424     John
7     P            333          2424     Lynda

我正在寻找只返回第2、3、6和7行的查询。

选择标准是当存在一行Code = T的行和另一行Code = P的行,但保留ID和CLientID相同时。 EmployeeID可以相同或不同(我想在结果中返回EmployeeID,但不要在选择条件中使用它)。

阅读论坛,我认为我需要自我加入(我不知道该怎么做)。您能提供的任何帮助将不胜感激!谢谢!

3 个答案:

答案 0 :(得分:3)

一种方法使用exists

select t.*
from t
where (t.code = 'T' and exists (select 1 from t t2 where t2.reservationId = t.reservationId and t2.clientId = t.clientId and t2.code = 'P'
                               )
      ) or
      (t.code = 'P' and exists (select 1 from t t2 where t2.reservationId = t.reservationId and t2.clientId = t.clientId and t2.code = 'T'
                               )
      );

为了提高性能,您希望在(reservationId, clientId, code)上建立索引。

答案 1 :(得分:1)

我认为更方便的方法是使用row_number窗口函数。您将以ReservationID的降序为同一ClientIDCode中的每一行提供一个行号,然后根据此编号进行过滤:

SELECT Row, Code, ReservationID, ClientID, EmployeeID
FROM   (SELECT Row, Code, ReservationID, ClientID, EmployeeID,
               ROW_NUMBER() OVER (PARTITION BY ReservationID, ClientID
                                  ORDER BY Code DESC) AS rn
        FROM   mytable) t
WHERE  rn = 1

答案 2 :(得分:0)

我认为最简单的解决方案是:

select distinct t1.*
  from my_table t1
  join my_table t2 on t1.reservationid = t2.reservationid
  where t1.code = 'T' and t2.code = 'P'
     or t1.code = 'P' and t2.code = 'T';