Though my sql knowledge is pretty good, I cannot get my head around the difference in a left vs inner join specifically when doing an update.
employee_table
column1:id
column2:socialsecurity
private_info_table
column1:id
column2:socialsecurity
I need to update employee_table.socialsecurity to be private_info_table.socialsecurity
should I do a left or inner join: ???
update e
set e.socialsecurity=p.socialsecurity
from employee_table e
join private_info_table p --should this be left or inner join?
on p.id=e.id
Left Join
Select *
from A
left join B on a.id = b.pid
In the conditions a.id = b.pid, every row is returned for both A and B BUT if the value from A (i.e. a.id) doesn't match the value from B (i.e., B), all fields of B will be null. On the other hand, for those rows where this condition is true, all values for B are shown. Notice that A's values have to be returned because it is on the left of the 'left' keyword.
Inner Join
Select *
from A
inner join B on a.id = b.pid
Rows are returned for rows where a.id = b.pid is true, otherwise no rows are returned if it is false. This is a mutually exclusive join.
In your case, don't use a left join because all records on the left of the 'left' keyword will be updated with null or non-null values. This means you will unintentionally update non-matched record with null values based upon my description of left joins.
It should be an inner join if you just want to update those records that are in both tables. If you do a left join it will update the employee table to be null wherever the id isn't found in the private info table.
The reason this matter is if you have some social security numbers in the employee table that already that aren't found in the private info table. You wouldn't want to erase them with a null value.
Related
Are next two queries going to return same result set?
SELECT * FROM tableA a
JOIN tableB b
ON a.id = b.id
WHERE a.id = '5'
--------------------------------
SELECT * FROM tableA a
JOIN tableb b
ON a.id = b.id
WHERE b.id = '5'
Also, will answer be different if LEFT JOIN is used instead of JOIN?
As written, they will return the same result.
The two will not necessarily return the same result with a left join.
Yes the result will be the same.
With a left join you will get every dataset of both table who got a ID.
With a join (Inner Join) you will get only the dataset's who a.id = b.id.
This site will explain you how to join https://www.w3schools.com/sql/sql_join.asp
Yes they will. A simple join works like an inner join by default. It checks for instances where the item you're joining on exist on both tables. Since you're joining on where a.id=b.id the results will be the same.
If you change the type of join to a left, the results will include all a.id's regardless of whether they are equal to 5.
I have two sql to join two table together:
select top 100 a.XXX
,a.YYY
,a.ZZZ
,b.GGG
,b.JJJ
from table_01 a
left join table_02 b
on a.XXX = b.GGG
and b.JJJ = "abc"
and a.YYY between '01/08/2009 13:18:00' and '12/08/2009 13:18:00'
select top 100 a.XXX
,a.YYY
,a.ZZZ
,b.GGG
,b.JJJ
from table_01 a
left join table_02 b
on a.XXX = b.GGG
where b.JJJ = "abc"
and a.YYY between '01/08/2009 13:18:00' and '12/08/2009 13:18:00'
The outcome of them is different but I don't understand the reason why.
I would be grateful if I can get some help here.
Whenever you are using LEFT JOIN, all the conditions about the content of the right table should be in the ON clause, otherwise you are effectively converting your LEFT JOIN to an INNER JOIN.
The reason for that is that when a LEFT JOIN is used, all the rows from the left table will be returned. If they are matched by the right table, the values of the matching row(s) will be returned as well, but if they are not matched with any row on the right table, then the right table will return a row of null values.
Since you can't compare anything to NULL (not even another NULL) (Read this answer to find out why), you are basically telling your database to return all rows that are matched in both tables.
However, when the condition is in the ON clause, Your database knows to treat it as a part of the join condition.
When doing an outer join, is it the order of the tables that matter or the order of the ON clause?
For example is
FROM TABLEA A
LEFT JOIN TABLEB B ON A.id = B.id
the same as
FROM TABLEA A
LEFT JOIN TABLEB B ON B.id = A.id
What about if you have multiple tables? Is it a LEFT JOIN if the first table out of many is the one you want all rows from regardless of the ON clause?
For example,
FROM TABLEA A
LEFT JOIN TABLEB B ON A.id = B.id
LEFT JOIN TABLEC C ON C.ID = A.ID
Does it take all the rows from TABLEA because it is to the left in the table list or the rows from C because it is on the left in the ON clause?
LEFT JOIN means take the table on the left (the first one specified), and join the rows from the table on the right (the second one specified). It will join them up based on the ON condition being true. Since the ON condition just needs to be true, the way it is written doesn't matter at all, it's just an expression that is evaluated.
LEFT JOIN ensures that every row from the table on the left is retained, and joined with NULLs if there is no row to join up to it from the table on the right. So that means that order of the tables is certainly significant.
If the table ordering was reversed, and there were only two tables, a RIGHT JOIN would have the same effect (i.e. keep the rows from the second table specified).
FROM TABLEA A LEFT JOIN TABLEB B ON A.id=B.id LEFT JOIN TABLEC C ON C.ID=A.ID
FROM TABLEA A LEFT JOIN TABLEB B ON B.id=A.id LEFT JOIN TABLEC C ON A.ID=C.ID
These both would return the same results.
FROM TABLEA A LEFT JOIN TABLEB B ON B.id=A.id LEFT JOIN TABLEC C ON B.ID=C.ID
This might or might not return the same results depending on what data is actually in table b and table C because table C is related to table b not directly related to table A. Personally I would always treat this as being different by definition than the first set of joins and that if is is the same that is accidental at this point in time.
When writing multiple joins especially when you have Outer joins, I personally find it helpful to start with the parent table (that usually being the one you want on the left side of the join) first and add any other other inner join tables before doing the left joins. If I have child and grandchild tables (vice multiple child tables), then I try to do in descending order of parent, child, grandchild to be clear what is related to what.
I want to INNER JOIN some tables and then insert a condition where the entries of a table are dependant on another table (that was not joined with the others)
Something like this:
SELECT * FROM TABLE_A AS a
INNER JOIN TABLE_B AS b ON b.id_b=a.id_a
INNER JOIN TABLE_C AS c ON c.id_c=b.id_b
Now I want to add a condition (possibly a "WHERE" clause) that only selects the values in a field in TABLE_C that match another condition, the existence of a value in a field in TABLE_D
Possible statement:
WHERE c.code=d.another_code AND d.reg_number LIKE 999%
How do i declare in the query the TABLE_D, since I do not want to Join it with the others?
In other words, I want to intersect 3 sets (A,B,C) and the other one (set D) is intersected only with set C
The title of the question Run-time error '13': ... doesn't seem to match the content so I'll just answer the SQL part.
Maybe this is what you want?
SELECT * FROM TABLE_A AS a
INNER JOIN TABLE_B AS b ON b.id_b=a.id_a
INNER JOIN TABLE_C AS c ON c.id_c=b.id_b
WHERE c.code = -- or possiby IN instead of =
(SELECT another_code FROM TABLE_D WHERE another_code LIKE '999%')
If the subquery can return multiple rows you need to use WHERE c.code IN instead of WHERE c.code =
SELECT * FROM Table A LEFT JOIN TABLE B LEFT JOIN TABLE C
From the snippet above, TABLE C will left join into (TABLE B) or (data from TABLE A LEFT JOIN TABLE B) or (TABLE A)?
TABLE C will left join into 1. (TABLE B) or 2. (data from TABLE A LEFT JOIN
TABLE B) or 3. (TABLE A)?
The second. But The join condition will help you to understand more.
You can write:
SELECT *
FROM Table A
LEFT JOIN TABLE B ON (A.id = B.id)
LEFT JOIN TABLE C ON (A.ID = C.ID)
But you are able to:
SELECT *
FROM Table A
LEFT JOIN TABLE B ON (A.id = B.id)
LEFT JOIN TABLE C ON (A.id = C.id and B.code = C.code)
So, you can join on every field from previous tables and you join on "the result" (though the engine may choose its way to get the result) of the previous joins.
Think at left join as non-commutative operation (A left join B is not the same as B left join A) So, the order is important and C will be left joined at the previous joined tables.
The Oracle documentation is quite specific about how the joins are processed:
To execute a join of three or more tables, Oracle first joins two of
the tables based on the join conditions comparing their columns and
then joins the result to another table based on join conditions
containing columns of the joined tables and the new table. Oracle
continues this process until all tables are joined into the result.
This is the logic approach to handling the joins and is consistent with the ANSI standard (in other words, all database engines process the joins in order).
However, when the query is actually executed, the optimizer may choose to run the joins in a different order. The result needs to be logically the same as processing the joins in the order given in the query.
Also, the join conditions may cause some unexpected conditions to arise. So if you have:
from A left outer join
B
on A.id = B.id left outer join
C
on B.id = C.id
Then, you might have the condition where A and C each have a row with a particular id, but B does not. With this formulation, you will not see the row in C because it is joining to NULL. So, be careful with join conditions on left outer join, particularly when joining to a table other than the first table in the chain.
You need to mentioned the column name properly in order to run the query. Let´s say if you are using:
SELECT *
FROM Table A
LEFT JOIN TABLE B ON (A.id = B.id)
LEFT JOIN TABLE C ON (A.id = C.id and B.code = C.code)
Then you may get the following error:
ORA-00933:SQL command not properly ended.
So to avoid it you can try:
SELECT A.id as "Id_from_A", B.code as "Code_from_B"
FROM Table A
LEFT JOIN TABLE B ON (A.id = B.id)
LEFT JOIN TABLE C ON (A.id = C.id and B.code = C.code)
Thanks