Postgresql query many to many relationship with left join and use where clouse not show data - postgresql

I have three table, table_1 (id), table_2(id), table_pivot(tbl1_id, tbl2_id). When I use query like this:
select *
from public.table_1 t1
left join public.table_pivot tp on tp.tbl1_id = t1.id and tp.user_id = 1
left join public.table_2 t2 on t2.id = tp.tbl2_id;
Data from table_1 is show. But when I use where condition. Like this:
select *
from public.table_1 t1
left join public.table_pivot tp on tp.tbl1_id = t1.id
left join public.table_2 t2 on t2.id = tp.tbl2_id
where tp.user_id = 1;
Data from table_1 not show.
I hope advance can help explain why?
Thanks.

Including a where clause on an outer joined table, effectively converts the join into an inner join. If there are no matching values in table_pivot, then
you will get no results at all. This is standard sql.

Related

Inner join if tables are empty with Top 1000 results

I have three table valued parameters passed into an SP. These all contain data to filter a query. I want to join them to a table as below but only if there is data in a table valued parameter
SELECT DISTINCT TOP (1000)
Person.col1,
Person.col2,
FROM dbo.Person INNER JOIN
#tbl1 t1 ON Person.col3 = t1.val INNER JOIN
#tbl2 t2 ON Person.col4 = t2.val INNER JOIN
#tbl3 t3 ON Person.col5 = t3.val
I am aware I can do a Left Outer Join but I don't want results with NULL values. The top 1000 necessary as there is a lot of data and scanning the whole table causes performance issues
Try use coalesce to cater nulls check
SELECT DISTINCT TOP (1000)
Person.col1,
Person.col2,
FROM dbo.Person INNER JOIN
#tbl1 t1 ON coalesce(Person.col3, '111') = t1.val INNER JOIN
#tbl2 t2 ON coalesce(Person.col4 , '111')= t2.val INNER JOIN
#tbl3 t3 ON coalesce(Person.col5, '111') = t3.val

I want to join 3 tables and select 1 coulmn from each table

I have tried using join as follows but it is not working
SELECT distinct(udf.FIELD_NAME),fun.FUNCTION_ID,mo.MODULE AS PRODUCT_MODULE FROM TABLE1 udf
JOIN TABLE2 mo
ON udf.PRODUCT_CODE = mo.PRODUCT_CODE
JOIN TABLE3 fun
ON udf.FIELD_NAME = fun.FIELD_NAME
where (udf.product_code in (select mo.product_code from TABLE2 mo))AND(udf.FIELD_NAME like '%UDF%')AND(udf.FIELD_NAME IN(SELECT fun.FIELD_NAME FROM TABLE3 fun));
I want all the where conditions mentioned here to work
There are some statements in your WHERE clause that mimic the join condition. If you do a join like this
JOIN TABLE2 mo
ON udf.PRODUCT_CODE = mo.PRODUCT_CODE
then there is no need to add the WHERE clause
where (udf.product_code in (select mo.product_code from TABLE2 mo))
because those 2 do the same. Unless you have duplicate rows, the "DISTINCT" clause is not needed either. Your query can be rewritten as:
SELECT
udf.field_name,
fun.function_id,
mo.module AS product_module
FROM
table1 udf
JOIN table2 mo ON udf.product_code = mo.product_code
JOIN table3 fun ON udf.field_name = fun.field_name
WHERE
udf.field_name LIKE '%UDF%';

What's the difference between these joins?

What's the difference between
SELECT COUNT(*)
FROM TOOL T
LEFT OUTER JOIN PREVENT_USE P ON T.ID = P.TOOL_ID
WHERE
P.ID IS NULL
and
SELECT COUNT(*)
FROM TOOL T
LEFT OUTER JOIN PREVENT_USE P ON T.ID = P.TOOL_ID AND P.ID IS NULL
?
The bottom query is equivalent to
SELECT COUNT(*)
FROM TOOL T
since it is not limiting the result set but rather producing a joined table with a lot of null fields for the right part of the join.
The first query is a left anti join.

Left join filtering only works on where clause

Can someone explain this to me?
I have two huge tables on which I wish to LEFT JOIN, but I think it would be more efficient to filter at the 'on' rather than the 'where'.
Select * from Table1 t1 left join Table2 t2 on t1.Id = t2.Id and t1.Enabled = 1
Rather than
Select * from Table1 t1 left join Table2 t2 on t1.Id = t2.Id where t1.Enabled = 1
The above results are not the same. No matter what I put in as filtering, it stays unaffected:
Select * from Table1 t1 left join Table2 t2 on t1.Id = t2.Id and t1.Enabled = 1
yields exactly the same results as
Select * from Table1 t1 left join Table2 t2 on t1.Id = t2.Id and t1.Enabled = 0
Also, Table1 might only have a few records where Enabled = 1, so it would be inefficient to join millions of records first and then filter to find only 10.
I can do a sub select first, but I somehow I feel it is not the right way:
Select * from (Select * from Table1 where Enabled = 1) a left join Table2 t2 on a.Id = t2.Id
Types of Joins
Left outer join All rows from the first-named table (the "left"
table, which appears leftmost in the JOIN clause) are included.
Unmatched rows in the right table do not appear.
When you move the condition to the where then t1.Enabled = 1 is applied
Do you have actual performance problems with the first query?

SQL: Joining tables using wildcards

When I join 2 tables
select t1.col1, t1.col2, t2.col3
from t1
left join t2
on t1.col2=t2.col3
Then I don't get any duplicate rows. However, when I try joining
tables using wildcards:
select t1.col1, t1.col2, t2.col3
from t1
left join t2
on t1.col2 like '%'||t2.col3
Then I'll get duplicate values. I saw this post that I think is
getting me somewhere but I couldn't really understand the solution.
Joining 2 Tables using a wildcard
It says I can use exists to get rid of duplicate values. I also
don't really understand his query. Here is the query in the other
post:
select *
from tableA a
where exists (select 1 from tableB b where a.id like '%' + b.id + '%');
What does the select 1 from tableB do?
I'm using PostgreSQL
This is what I've tried even though I don't understand it and still gives me duplicates:
select t1.col1,t1.col2,t2.col3
from t1
left join t2
on t1.col2 like '%'||t2.col3
where exists (select 1 from t2 where t1.col2 like '%'||t2.col3)
Use the DISTINCT clause:
SELECT DISTINCT t1.col1, t1.col2, t2.col3
FROM t1
LEFT JOIN t2 ON t1.col2 LIKE '%'||t2.col3;