(N.B. This isn't an answer, as it looks like Giorgos's answer is what you were really after, but it's too long to go in a comment. I wanted to make sure you understood why your original query isn't doing what (I think) you think it is)
Your original query actually ends up doing an inner join, because you're asking for specific values for the b.empno and c.empno columns without including them in the left outer join. I.e. you're saying "first, left outer join b to a, and then afterwards, filter out any rows which don't have a b.empno = 190". That will get rid of any rows where b.empno is null as well as other b.empno values.
Here's a simple example showing the different behaviours:
Old-style left outer join with non-left outer join filter:
WITH t1 AS (SELECT 1 ID, 10 val FROM dual UNION ALL
SELECT 2 ID, 20 val FROM dual UNION ALL
SELECT 3 ID, 30 val FROM dual),
t2 AS (SELECT 1 ID, 100 val FROM dual UNION ALL
SELECT 1 ID, 150 val FROM dual UNION ALL
SELECT 2 ID, 200 val FROM dual UNION ALL
SELECT 2 ID, 250 val FROM dual)
SELECT t1.id, t1.val, t2.val
FROM t1,
t2
WHERE t1.id = t2.id(+)
AND t2.val = 200
ORDER BY t1.id, t2.val;
ID VAL VAL
---------- ---------- ----------
2 20 200
Old-style inner join with filter:
WITH t1 AS (SELECT 1 ID, 10 val FROM dual UNION ALL
SELECT 2 ID, 20 val FROM dual UNION ALL
SELECT 3 ID, 30 val FROM dual),
t2 AS (SELECT 1 ID, 100 val FROM dual UNION ALL
SELECT 1 ID, 150 val FROM dual UNION ALL
SELECT 2 ID, 200 val FROM dual UNION ALL
SELECT 2 ID, 250 val FROM dual)
SELECT t1.id, t1.val, t2.val
FROM t1,
t2
WHERE t1.id = t2.id
AND t2.val = 200
ORDER BY t1.id, t2.val;
ID VAL VAL
---------- ---------- ----------
2 20 200
You can see that the results of the above two queries are identical, which means the first query with the left outer joins is really doing an inner join. And the ANSI join syntax equivalent query to this would be:
ANSI-style inner join with filter:
WITH t1 AS (SELECT 1 ID, 10 val FROM dual UNION ALL
SELECT 2 ID, 20 val FROM dual UNION ALL
SELECT 3 ID, 30 val FROM dual),
t2 AS (SELECT 1 ID, 100 val FROM dual UNION ALL
SELECT 1 ID, 150 val FROM dual UNION ALL
SELECT 2 ID, 200 val FROM dual UNION ALL
SELECT 2 ID, 250 val FROM dual)
SELECT t1.id, t1.val, t2.val
FROM t1
INNER JOIN t2 ON t1.id = t2.id
WHERE t2.val = 200;
ID VAL VAL
---------- ---------- ----------
2 20 200
You can see the difference to the results by including the filtered column in the outer join in the original old-style query:
Old-style left outer join with left outer join filter
WITH t1 AS (SELECT 1 ID, 10 val FROM dual UNION ALL
SELECT 2 ID, 20 val FROM dual UNION ALL
SELECT 3 ID, 30 val FROM dual),
t2 AS (SELECT 1 ID, 100 val FROM dual UNION ALL
SELECT 1 ID, 150 val FROM dual UNION ALL
SELECT 2 ID, 200 val FROM dual UNION ALL
SELECT 2 ID, 250 val FROM dual)
SELECT t1.id, t1.val, t2.val
FROM t1,
t2
WHERE t1.id = t2.id(+)
AND t2.val(+) = 200
ORDER BY t1.id, t2.val;
ID VAL VAL
---------- ---------- ----------
1 10
2 20 200
3 30
And, as per Giorgos's answer, the equivalent ANSI join syntax query would be:
ANSI-style outer join with outer join filter:
WITH t1 AS (SELECT 1 ID, 10 val FROM dual UNION ALL
SELECT 2 ID, 20 val FROM dual UNION ALL
SELECT 3 ID, 30 val FROM dual),
t2 AS (SELECT 1 ID, 100 val FROM dual UNION ALL
SELECT 1 ID, 150 val FROM dual UNION ALL
SELECT 2 ID, 200 val FROM dual UNION ALL
SELECT 2 ID, 250 val FROM dual)
SELECT t1.id, t1.val, t2.val
FROM t1
left OUTER JOIN t2 ON t1.id = t2.id AND t2.val = 200
ORDER BY t1.id, t2.val;
ID VAL VAL
---------- ---------- ----------
1 10
2 20 200
3 30