Left Outer Join, No result in final query - sql

I'm executing the following query
Select * from A a left outer join B b on (b.id = a.id)
I'm getting one record from A and no records from B. I'm expecting one record in final select query but getting none.
Here is some sample data:
A
v_id, id, date, d_id
1, 1244578, 02-MAR-11, 1827877
B, no data presented:
e_id,id,amount
What am I doing wrong? How can I get it do like this ?

This should work fine:
Select *
from A a
left outer join B b on b."id" = a."id"
See it in action here:
SQL Fiddle Demo
This will give you:
| V_ID | ID | DATE | D_ID | E_ID | AMOUNT |
----------------------------------------------------------
| 1 | 1244578 | 02-MAR-11 | 1827877 | (null) | (null) |

You are getting one record from Table A this is because table A has only one record and Table B have no record.
In left outer join content of first table is show in result join with second table but in your case second table have no records so final result show null values for that records.

Related

Count rows from left table without corresponding value in the right table

I want to count rows from left table (of a 1-to-many relation between two tables) that do not have PK-FK representative in right table
Left table
id | value
-----------
1 | a
2 | b
3 | c
Right table
id | id-left | value
--------------------
.. | 1 | ....
the expected result is 2 as rows with id 1 and 3 in left table have no counterpart in right table.
You can use a not exists anti-semi-join:
select count(*)
from l
where not exists (
select * from r where r.id_left = l.id
);

How can I get full results in SQL query using 3 tables, where 1 of them keeps relation of 2 another?

I need help writing a query to display results I want.
"Table 3 - relations" keeps all relations between table 1 and 2.Often, relation between table 1 and 2 will not exist in table 3 so I want to see missing relation in the results for all Table 1 rows - see expected Results below.
I can't modify these tables - I have only SELECT privilege.
Data and expected result below:
Table 1 - a:
a_id, a_name
e.g.:
1 A
2 B
Table 2 - b:
b_id, b_name
e.g.:
1 X
2 Y
Table 3 - relation:
asset1_id (it's always id from Table 1), asset2_id (it's always id from Table 2), relation_type
e.g.:
1 1 covers
1 2 covers
Expected result:
Table1_name, Table2_name, Table3_relation_type (including NULL for b_name and relation_type when such relation does not exist in Table 3 - relation)
e.g.
A X covers
A Y covers
B NULL NULL
I can't get the 3rd expected line with NULLs.
I think that this query will produce those results.
select a.name as a_name,b.name as b_name, r.relation_type from relation r
join a on a.id=r.asset1_id
join b on b.id=r.asset2_id
union
select a.name as a_name,b.name as b_name,r.relation_type from relation r
full outer join a on a.id=r.asset1_id
full outer join b on b.id=r.asset2_id
where a.id is null or b.id is null
With your data sample you could try this one.
It should work both hive or impala.
SELECT t1.name ,t2.name ,r.relation_type
FROM relation r
FULL OUTER JOIN table1 t1 ON(t1.id = r.id1)
FULL OUTER JOIN table2 t2 ON(t2.id = r.id2);
+------+------+---------------+
| name | name | relation_type |
+------+------+---------------+
| A | X | covers |
| A | Y | covers |
| B | NULL | NULL |
+------+------+---------------+
WITH
cte_A AS (
SELECT id as a_id, name as a_name
FROM a
),
cte_C AS (
SELECT c.asset_id1 as a_id, b.name, c.relation
FROM c
LEFT JOIN b ON c.id=b.asset_id2
)
SELECT cte_A.a_name, cte_C.name as c_name, cte_C.relation
FROM cte_A
LEFT JOIN cte_C ON cte_A.a_id=cte_C.a_id

SQL get left join values from left table

I am working on a complex sql query. Just for explaning purpose of my issue i have reduced to the below short query:
select a.column1 as field1,b.column2 as field 2,c.column3 as field3,COALESCE(SUM(d.paid_amt) OVER (PARTITION BY a.some_column),0) as amount_paid
from a Inner join b on b.column3=ac.olumn2
right join c on c.column4=b.column1
left join d on d.column2=a.column1 and d.column5 = a.column1
where ...//some conditions
SO i am quite sure whats happening here. I am more concerned on the last left join on d table. if the d table has no records which matches d.column5 = a.column1 then i am not getting any results.
But i am trying to write the query in such a way that if d table retuns any values with the where condition d.column5 = a.column1 then i want to use those values or else if there are no records in d table i just want to get the records from the result of previous joins and get the records that i need.
Here with the current query the problem is as expected, if the join doesnt match the where condition its eliminating all the records. I want to have the records no matter what if the where condition satisfies or not.
I am not quite sure how to do this in one single query. Any suggestions are appreciated.
Note: #scaisEdge and #Zaynul Answer works fine. but the problem is the amount caluclation if i move the condition in line on join and clause. The am ount calculation should also be on the same condition d.column5 = a.column1.So i am not really sure how to overcome this :(
Sample date below:
field1 | field2 | field3 | ampount_paid | some_column_to_match
--------------------------------------------------------------
name | value1 | other1 | 100 | 1
name1 | value2 | other2 | 100 | 1
name2 | value3 | other3 | 100 | 2
So i have just added the last columns to explain how i want the sum. I want sum the fields only if the some_column_to_match matches. So i am trying to get the output like:
field1 | field2 | field3 | amount_paid | some_column_to_match
--------------------------------------------------------------
name | value1 | other1 | 200 | 1
name1 | value2 | other2 | 200 | 1
name2 | value3 | other3 | 100 | 2
So basically the calculation should be the sum of all values in amount_paid where some_column_to_match value matches. So in the above example, the first two columns should return 200 as it as 100 in each individual field for the same value.
If you want a left join then you should not use columns of left joined table (d.column5 = a.column1) in where condition in this way the join became an inner join
In these case add the condition for the columns related to the left join table at the corresponding ON clase
select a.column1
,b.column2
,c.column3
,d.column4
from a Inner join b on b.column3=ac.olumn2
right join c on c.column4=b.column1
left join d on d.column2=a.column1 AND d.column5 = a.column1

Oracle - Conditional Join eliminating additional joins where unnecessary

Let’s say I have a simplified table structure as follows:
Table A - ID (PK)
Table B - ID (PK), AID = FK to Table A
Table C - ID (PK), BID = FK to Table B
Table D - ID (PK), CID = FK to Table C
Query something like so:
SELECT * FROM TABLE_A TBLA
LEFT JOIN TABLE_B TBLB ON TBLA.ID = TBLB.AID
LEFT JOIN TABLE_C TBLC ON TBLB.ID = TBLC.BID
LEFT JOIN TABLE_D TBLD ON TBLC.ID = TBLD.CID
It’s relatively straight-forward but what I want to do is somewhat a conditional join in that I want all records from TABLE A but want to join TABLE B -> TABLE C -> TABLE D if the first join between TABLE A and TABLE B is satisfied, bearing in mind that I could change TABLE B -> TABLE C -> TABLE D joins to be INNER as there’ll exist in that initial join between TABLE A and TABLE B is satisfied.-
But also I’d need a WHERE condition on TABLE D also.
So essentially want to eliminate the LEFT JOIN’S between TABLE_B, TABLE_C, TABLE_D where join isn’t satisfied between TABLE_A and TABLE_B.
Very simplified data so apologies!
| Table A |
| ID |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| Table B |
| ID | AID |
| 1 | 5 |
| Table C |
| ID | BID |
| 1 | 1 |
| Table D |
| ID | CID | Value |
| 1 | 1 | ABC |
The reason I want to eliminate the join is that for 4 of the 5 rows in Table A, I’m doing unnecessary joins across three tables to get the value in Table D.
You can use brackets with join, but not sure if that would help you!
SELECT * FROM
TABLE_A TBLA
LEFT JOIN (TABLE_B TBLB
INNER JOIN TABLE_C TBLC ON TBLB.ID = TBLC.BID
INNER JOIN TABLE_D TBLD ON TBLC.ID = TBLD.CID) ON TBLA.ID = TBLB.AID
This way, when you have A matches entries in B, but B is not matched in the chain to C and D, B data is not retrieved, and so for C
You mentioned that you need a where condition on table D? Does that mean that you always have to link to D?! Note that if you have a condition on D, the condition has to be satisfied in all cases. Hence, when no records are retrieved from D, no records will be retreived from the query (even with your initial outer join unless you used OR .. is null )

Join 2 Tables and display everything

I have 2 simple tables:
table a:
id | txt
---+----
0 | aaa
1 | bbb
2 | ccc
table b:
id | tel
---+----
0 | 000
2 | 111
I am trying to join 2 tables like this:
SELECT a.*,b.*
FROM a,b
WHERE a.id=b.id
It works, but, if there is no entry in the "b" table it wont show anything.
what the sql shows is something like this:
id | txt | tel
---+-----+----
0 | aaa | 000
2 | ccc | 111
I also want to list the "empty" row a.id=1:
id | txt | tel
---+-----+-----
1 | bbb | NULL
Any ideas? Thanks!
(SQL is for MS Access / oledb)
You want a left outer join (or a full outer join, if you want rows in which there is no entry in the a table also).
SELECT a.*,b.* FROM a LEFT OUTER JOIN b ON a.id=b.id
Depending the system, the syntax LEFT JOIN may work as well.
In MSAccess query designer, right click on the relationship connection between the two tables, and edit its properties. Modify it to 'show all records from table a'.
This:
SELECT a.*,b.*
FROM a, b
WHERE a.id = b.id
...is ANSI-89 inner join syntax, and I highly recommend using ANSI-92 syntax instead:
SELECT a.*,
b.*
FROM TABLE_A a
JOIN TABLE_B b ON b.id = a.id
...mostly because ANSI-88 syntax for left joining to tables wasn't consistently implemented on various databases. This will return the results you expect:
SELECT a.id,
a.txt,
b.tel
FROM TABLE_A a
LEFT JOIN TABLE_B b ON b.id = a.id
A LEFT JOIN means you'll get all the records from TABLE_A in this example, and when there is a matching record (based on the ON criteria) in TABLE_B, the value will be displayed. Otherwise, the TABLE_B column references will return NULL values.
For more information on JOINs, see this page for a great pictorial demonstration of what each one represents and how they compare.