Here is an alternative, which may or may not be faster for your data than @avk's answer (you'd have to test):
with sample_data (title_code, product_number, format_code) as (select 1234, 'A1', 'OC' from dual union all
select 1234, 'A2', 'HB' from dual union all
select 1234, 'A3', 'PB' from dual union all
select 2345, 'B1', 'OC' from dual union all
select 2345, 'B2', 'HB' from dual union all
select 3456, 'C1', 'OC' from dual union all
select 7890, 'D1', 'OC' from dual union all
select 7890, 'D2', 'TD' from dual)
select title_code,
product_number,
format_code
from (select title_code,
product_number,
format_code,
max(case when format_code = 'OC' then 1 else 0 end) over (partition by title_code) oc,
max(case when format_code = 'PB' then 1 else 0 end) over (partition by title_code) pb,
max(case when format_code = 'HB' then 1 else 0 end) over (partition by title_code) hb
from sample_data)
where oc = 1
and pb = 0
and hb = 0;
TITLE_CODE PRODUCT_NUMBER FORMAT_CODE
---------- -------------- -----------
3456 C1 OC
7890 D1 OC
7890 D2 TD
N.B. I have added in the case where one of the title_codes has a format_code of something other than OC, HB and PB; depending on what you wanted to display, you may want to add in an additional where clause of and format_code = 'OC'. You also haven't said what you'd want displaying if there were two rows with a format_code of OC...
WHERE format_code ='OC'is enough to filter the rows. What is the need to explicitly filter other codes, when all you need it format_code = 'OC'.where format_code = 'OC'