Reputation: 29
It may not be a self-join I need, but I'm having difficulty with this problem and I hope someone can help me.
Sample Data:
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
Desired output:
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
I'm looking for a query that will only return Rows 2, 3, 6, and 7.
The selection criteria is when there is a row with Code = T and another row with Code = P but for the same Reservation ID and CLientID. The EmployeeID may be the same or different (I want to return the EmployeeID in the results but not use it in the select criteria).
Reading forums I think I need a self-join (which I don't know how to do). Any help you can offer would really be appreciated! Thanks!
Upvotes: 0
Views: 826
Reputation: 1270091
One method uses 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'
)
);
For performance, you want an index on (reservationId, clientId, code)
.
Upvotes: 3
Reputation: 48820
I think the simplest solution is:
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';
Upvotes: 0
Reputation: 311573
I think a more convenient way would be to use the row_number
window function. You'd give a row number for every row within the same ReservationID
and ClientID
in a descending order of Code
, and then filter according to this numbering:
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
Upvotes: 1