find the number of records that left outer join,right outer join and full outer join return
Since you know the total number of records, knowing the number of unmatched records is equivalent to knowing the number of matched records. (Perhaps!)
The answer to your question is NO, you can't determine the number of records in different types of joins by only knowing the cardinalities of the base tables, without knowing how many records are matched (or unmatched). Simple mental exercise: both tables have 100 records. If all are perfectly matched, one-to-one, then all joins are the same as the inner join, and they all have 100 records. If there are no matches at all, the inner join has zero rows, the one-sided joins have 100 rows and the full outer join has 200 rows. And the only difference between these cases is the number of matched (or unmatched) records, there is absolutely nothing else that you might know that will allow you to get the answer without this piece of information.
ADDED after the OP asked a follow-up question:
In fact knowing "how many records are matched" is not well defined, and insufficient anyway. Suppose ALL records from both tables are matched. At one extreme, the matches may be in pairs: there is an id column in both tables, and the values in both tables are all the possible values from 1 to 100. Then the result has 100 rows. On the other hand, suppose the "id" is not unique in either table. Instead, it has the value 1 IN ALL 100 ROWS IN BOTH TABLES. Then every row in the first table matches every row in the second table, and the result set will have 100 x 100 = 10,000 rows.
This is just to suggest the following: "how many rows are matched" is not a well-defined concept. To have a count of the resulting joins (of different kinds), one needs to know what the joins are on, and for each tuple in the join condition, how many rows have that specific tuple in each table. Then the number of rows in the result set of an inner join is a sum of products of such tuple-grouped counts, and additional rows for unmatched rows from the left (or right, or both) table(s) for outer joins.
Oracle using (+) for left outer join
Need to include the (+)
Operator on the Condition with the Literal
The older outer join approach requires that you include the (+)
operator for the condition on the literal.
Just put your "retro" mental cap on and return back to the 90's. :)
Here is how it should look with this approach:
SELECT
c
.DATE,
u.user_id
FROM
order_detail_trans c,
order_detail_trans u
WHERE
u.trans_id (+) = c.trans_id
AND u.trans_type (+) = 'UPDATE DETAIL'
Here is an example with the tables, emp
and dept
:
SCOTT@db>SELECT
2 d.deptno,
3 e.job
4 FROM
5 dept d
6 LEFT OUTER JOIN emp e ON d.deptno = e.deptno
7 and e.job = 'CLERK'
8 GROUP BY
9 d.deptno,
10 e.job
11 ORDER BY
12 1,
13 2;
DEPTNO JOB
10 CLERK
20 CLERK
30 CLERK
40
SCOTT@db>SELECT
2 d.deptno,
3 e.job
4 FROM
5 dept d,
6 emp e
7 WHERE
8 d.deptno = e.deptno (+)
9 AND e.job (+) = 'CLERK'
10 GROUP BY
11 d.deptno,
12 e.job;
DEPTNO JOB
20 CLERK
30 CLERK
10 CLERK
40
Believe it or not, I believe most Oracle Applications shops just use this older outer join approach.
Multiple LEFT OUTER JOIN on multiple tables
The join
on D
is an inner join, the rest are left outer joins:
SELECT *
FROM TABLEA A JOIN
TABLED D
ON D.Z = A.Z LEFT JOIN
TABLEB B
ON A.X = B.X LEFT JOIN
TABLEC C
ON B.Y = C.Y
WHERE MY_COL = @col_val;
I always start chains of joins with inner joins followed by the left outer join
. I never use right join
, and full join
rather rarely. The inner joins define the rows in the result set, so they come first.
Left outer join and necessary subquery with date in Oracle
As MT0 suggested using partitioning and sorting by row number helped. Only had to include value_code in the partitioning for my purpose.
So this query finally did what I wanted:
SELECT *
FROM CONTRACTS C
LEFT JOIN
( SELECT *
FROM (
SELECT V.*,
ROW_NUMBER() OVER ( PARTITION BY CUSTOMER_ID, VALUE_CODE ORDER BY BEGIN_DATE DESC )
AS rn
FROM VALUES V
)
WHERE rn = 1
) V
ON ( C.CUSTOMER_ID = V.CUSTOMER_ID
AND VALUE_CODE = 'VOLUME' )
WHERE C.STATUS = 'ACTIVE'
Oracle - Left outer join with where clause
Your explanation does not correlate with your query. You have mentioned
"However I also need to include a where clause but.... I still want a row from the left-hand table to be returned for each record in the left-hand table even if the condition in the where clause isn't met."
So I believe your query looks something like this
SELECT a.*,
b.*
FROM a
LEFT OUTER JOIN b
ON a.vin = b.vin
WHERE Trunc(a.rep_open_date) BETWEEN Trunc(b.check_in_date) + 1 AND
Trunc(b.check_in_date) - 1
In the above the LEFT OUTER JOIN
will be converted into INNER JOIN
due to the filtration of right table in Where
clause
So as you have used in first query the right table filters should be part of JOIN
condition, Which will return rows from LEFT table even though there is no matching records in RIGHT side table.
SELECT a.*,
b.*
FROM a
left outer join b
ON a.vin = b.vin
AND Trunc(a.rep_open_date) BETWEEN
Trunc(b.check_in_date) + 1 AND
Trunc(b.check_in_date) - 1
Update :
You have used between operator like 10 between 11 and 9
but it should be 10 between 9 and 11
SELECT a.*,
b.*
FROM a
left outer join b
ON a.vin = b.vin
AND CAST(a.rep_open_date as date) BETWEEN
CAST(b.check_in_date as date) - 1 AND
CAST(b.check_in_date as date) + 1
Related Topics
Group by and Count Using Activerecord
How to Combine Results of Two Queries into a Single Dataset
Curious Issue with Oracle Union and Order By
Oracle Get Checksum Value for a Data Chunk Defined by a Select Clause
How to Give an Alias to a Table in Oracle
What Are the Uses for Cross Join
Converting Int to Real in SQLite
How to Detect If a String Contains at Least a Number
SQL - How to Get Only the Numbers After the Decimal
How to Get the Value of Autoincrement of Last Row at the Insert
How to Do "Where Exists" in Arel
Stored Procedure Exec VS Sp_Executesql Difference
Oracle Date To_Char('Month Dd, Yyyy') Has Extra Spaces in It
How to Design a Schema Where the Columns of a Table Are Not Fixed
Order by with Inner Query, Giving Ora-00907 Missing Right Parenthesis
In Postgresql, Force Unique on Combination of Two Columns