when condition is true then inner join comes in sql server - sql

I want to do inner join when some condition is true
case
when (select dbo.fnGetProduct_config('CATEGORY_NAME','',''))='XYZ'
then inner join product_master t12 on t12.id=t1.product_id
END

You can't use a conditional to decide whether or not to join (except with dynamic sql), but you can add the predicate to the join....
...
from table1
inner join product_master t12 on t12.id=t1.product_id and dbo.fnGetProduct_config('CATEGORY_NAME','',''))='XYZ'

SELECT * FROM TABLE1 T1
INNER JOIN TABLE2
ON (fn(T1.Blahblah)==1 AND /*other conditions*/)

Related

left join and group of inner join

Say, I have the following query:
SELECT * FROM TABLE1
JOIN TABLE2 ON ...
LEFT JOIN TABLE3 ON ...
JOIN TABLE3_1 ON ...
JOIN TABLE3_2 ON ...
JOIN TABLE3_3 ON ...
What I want to achieve is for TABLE3, TABLE3_1, TABLE3_2, TABLE3_3 to have inner joins within them (I only need all the matching data between them, the rest gone). Then for TABLE1, TABLE2 to have inner joins too. But from TABLE1 + TABLE2 result, some won't have a corresponding entries to TABLE3, and that's okay, I will still want it.
Using the above pseudo code if I run it as it is, obviously it will not achieve the same result.
Use paretheses to force joins order, kind of
SELECT *
FROM (
TABLE1
JOIN TABLE2 ON ...)
LEFT JOIN (
TABLE3
JOIN TABLE3_1 ON ...
JOIN TABLE3_2 ON ...
JOIN TABLE3_3 ON ...) ON ...
Check this answer.
#Serg answer is correct but you do not need to use parentheses if you specify the ON condition at the end of the statement.
SELECT * FROM TABLE1
JOIN TABLE2 ON ...
LEFT JOIN TABLE3 ON ThisConditionShouldBeAtTheEnd
JOIN TABLE3_1 ON ...
JOIN TABLE3_2 ON ...
JOIN TABLE3_3 ON ...
you rewrite like this:
SELECT * FROM TABLE1
JOIN TABLE2 ON ...
LEFT JOIN TABLE3
JOIN TABLE3_1 ON ...
JOIN TABLE3_2 ON ...
JOIN TABLE3_3 ON ...
ON ThisConditionShouldBeAtTheEnd
See also this article for more explanation. The reason is that JOIN conditions are evaluated from left to right (top-down) and you need the LEFT join condition to be evaluated after previous inner joins.
Disclaimer: I didn't have a oracle DB at hand to check but hopefully it will contain ideas to help you.
Solution 1: You could use parenthesis to state the intermediate joined table of (TABLE3 x N). Pseudo-code:
select *
FROM TABLE1
inner join TABLE2 on (condition)
left join (
table3
inner join table3_1 on (condition)
inner join table3_2 on (condition)
inner join table3_3 on (condition)
) as table3_joined ON (table3_joined.ID = table2.id)
It works on MSSQL, at least. I cannot verify it works in oracle as well, but you could try. I consider this syntax very explicit and easy to follow/maintain.
Solution2: Alternative is to reuse the same left-to-right order that's troubling you for your advantage using right join. Pseudo-code:
select *
from table3
inner join table3_1 on (condition)
inner join table3_2 on (condition)
inner join table3_3 on (condition)
right join table2 on (condition)
inner join table1 on (condition)
This syntax probably works but imho using right joins makes the syntax a bit more uncomfortable to reason about.
An alternative to the other answers is a CTE (common table expression). This just has a query for the inner joined table3 group and a query for the inner joined table1/table 2 group and those two groups are outer joined in the main query. For me (and obviously this is subjective) I would find this easier to understand what was going on if I came across it in someone else's code.
WITH
t3_group AS
(SELECT *
FROM table3 ON ...
INNER JOIN table3_1 ON ...
INNER JOIN table3_2 ON ...
INNER JOIN table3_3 ON ... ),
t1_t2_group AS
(SELECT *
FROM table1
INNER JOIN table2 ON ...)
SELECT *
FROM t1_t2_group
LEFT JOIN t3_group ON ...

Can we get result of left outer join using right outer join

Can we get the results of a left outer join using a right outer join?
Yes, you can do this. A right (outer) join is equivalent to a left (outer) join with the position of the tables switched.
Hence, the following query:
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
ON t1.col = t2.col
is equivalent to
SELECT *
FROM table2 t2
RIGHT JOIN table1 t1
ON t1.col = t2.col

SQL JOIN USING and WHERE

This is somewhat of a followon to SQL JOIN where to place the WHERE condition?
I would prefer to use the USING clause on the join, but am not yet able to put the field value condition with the join.
SELECT 1
FROM table1 t1
JOIN table2 t2 USING(id) AND t2.field = 0;
ORA-00933: SQL command not properly ended
Is it possible to have USING and another condition as part of the JOIN clause?
You can use:
SELECT 1
FROM table1 t1
JOIN table2 t2 USING(id)
WHERE t2.field = 0;
Using USING(id) is like using ON t1.id = t2.id except that in the JOIN result instead of two columns t1.id & t2.id there is only one id column.
For INNER JOIN USING with a condition followed by an OUTER JOIN you need a subquery to keep the WHERE with the USING:
SELECT ...
FROM (SELECT id, ...
FROM table1 t1
JOIN table2 t2 USING(id)
WHERE t2.field = 0) s
LEFT JOIN ...;
For an OUTER JOIN USING with a condition you need a subselect:
SELECT ...
FROM table1 t1
LEFT JOIN (SELECT *
FROM table2 t2
WHERE t2.field = 0) t2
USING (id);
See this re ON/WHERE with JOIN. See this re ON/WHERE when mixing INNER & OUTER JOINs.

SQL join order and conditions

I've got 3 tables that I want to join and filter on some conditions.
I've first wrote this query:
select * from table1 t1
left join (select * from table2 where table2.fieldX=...) t2
on t1.id_12=t2.id_12
left join table3
on t2.id_23=t3.id_23
where t1.fieldY=...
Then I wanted to make it looks like more canonical by rewritting it like that:
select * from table1 t1
left join table2 t2
on t1.id_12=t2.id_12
left join table3
on t2.id_23=t3.id_23
where table2.fieldX=...
and t1.fieldY=...
But it does not give the same result.
I dont't understand why...
Do you?
Thanks in advance.
When you put table2.fieldX=... in the where clause you eliminate all rows from table1 that do not have a corresponding row in table2. Effectively you are changing the left join into an inner join.
Instead, you can apply the table2 filter in the join itself:
SELECT
*
FROM
Table1 t1
LEFT JOIN Table2 t2 ON t1.id_12 = t2.id_12 AND t2.fieldX = ...
LEFT JOIN Table3 t3 ON t2.id_23 = t3.id_23
WHERE
t1.fieldY = ...
Did you add the inner select where on the second query?
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
on t1.id_12=t2.id_12
LEFT JOIN table3
on t2.id_23=t3.id_23
WHERE t1.fieldY=...
and t2.fieldX=...

Is it possible to join the new style inner join with an outer join?

Is it possible to combine the new inner join style with an outer join?
For example, something like:
select * from
table1, table2
where table1.columnA = table2.columnB
left outer join table3
on table3.columnA = table1.columnA
Yes, but you have to put the WHERE clause after all your FROM and JOIN clauses:
select *
from table1, table2
left outer join table3 on table3.columnA = table1.columnA
where table1.columnA = table2.columnB
But it's ugly and confusing so I wouldn't exactly recommend it. Stick with one style.
If you are using INNER and (LEFT) OUTER JOIN, they must come before the WHERE clause.