In MySQL JOIN means which join perform..? - mysql

It's to confusing, I have query where I have write JOIN with multiple table then which type of join it'll perform..?
For example :
SELECT
b.*
FROM
tbl_bookings b
JOIN tbl_users ua ON ua.id = b.act_id
JOIN tbl_users uc ON uc.id = b.cust_id
JOIN tbl_venue v ON b.venue_id = v.venue_id
WHERE
b.act_id = 4
Can any one please let me know by which type of join it'll perform..?

JOIN equals to an INNER JOIN . They are functionally equivalent, but INNER JOIN can be a bit clearer to read, especially if the query contains other type of JOIN
For something other than INNER JOIN you should specify the join you want.
LEFT JOIN / RIGHT JOIN which are the same as LEFT OUTER JOIN and RIGHT OUTER JOIN .
Those are just different ways of saying the same thing.

It will perform INNER JOIN. It is good to write INNER JOIN when you have different types of joins in query.

Related

MS Access 2013 SQL Query LEFT JOIN

FROM (((Project
INNER JOIN MDS ON Project.PID=MDS.PID)
INNER JOIN PLocation ON Project.PID = PLocation.PID)
INNER JOIN Site ON PLocation.ACode = Site.ACode) AS [Prim]
LEFT JOIN ((Procurement INNER JOIN MagicT ON Procurement.PRNum = MagicT.PRNum)
INNER JOIN DO ON DO.DoNum = MagicT.DONum) AS [Prim2] ON Prim.PRNum = Prim2.PRNum
Hey guys. So the above from statement is giving me an error:
Syntax error in from clause
Funny thing is when I make the LEFT JOIN an INNER JOIN it runs fine, but sadly that isn't what I want. I read that I had to rename the inner queries and join them using their new names but unfortunately I do not think I did it properly.
Maybe this... using two inline views. but you should be able to do this with just ()'s in Access... however if you have same named columns in each of Prim/prim2 tables, this will present with errors you may have to spell out each of the column names needed in the inline views.
FROM (SELECT * FROM Project
INNER JOIN MDS ON Project.PID=MDS.PID
INNER JOIN PLocation ON Project.PID = PLocation.PID
INNER JOIN Site ON PLocation.ACode = Site.ACode) PRIM
LEFT JOIN (SELECT * from Procurement
INNER JOIN MagicT ON Procurement.PRNum = MagicT.PRNum
INNER JOIN DO ON DO.DoNum = MagicT.DONum) PRIM2
ON Prim.PRNUM = Prim2.PRNUM
--- maybe... in access the ()'s will handle the outer join but I don't know what table PRNUM is sourced from in (project, mds, plocation,site) so project is a guess...
FROM Project
INNER JOIN MDS ON Project.PID=MDS.PID
INNER JOIN PLocation ON Project.PID = PLocation.PID
INNER JOIN Site ON PLocation.ACode = Site.ACode
LEFT JOIN (SELECT * from Procurement
INNER JOIN MagicT ON Procurement.PRNum = MagicT.PRNum
INNER JOIN DO ON DO.DoNum = MagicT.DONum) PRIM2
ON Project.PRNUM = Prim2.PRNUM
You basically have
FROM Subquery1 LEFT JOIN Subquery2
but your subqueries don't have SELECT in them.
I think it should be:
FROM
(SELECT Prim.PRNum FROM
(((Project
INNER JOIN MDS ON Project.PID=MDS.PID)
INNER JOIN PLocation ON Project.PID = PLocation.PID)
INNER JOIN Site ON PLocation.ACode = Site.ACode)
AS [Prim])
LEFT JOIN
(SELECT Prim2.PRNum FROM
((Procurement INNER JOIN MagicT ON Procurement.PRNum = MagicT.PRNum)
INNER JOIN DO ON DO.DoNum = MagicT.DONum)
AS [Prim2])
ON Prim.PRNum = Prim2.PRNum
(edit: a little too late...)
I have also discovered one of my issues here, is that in Access, you can have a left or right join nested inside an inner join but CANNOT have an inner join inside a left or right join. Rewriting the query to not include these joins inside the inner joins has solved the issue.
Thank you for all the help.

Inner join on four tables on MySQL

I am trying to do an inner join on four tables in MySQL. The table names are:
question (id_question, question_text, id_standard)
standard (id_standard, standardtext)
organisation_standard(id_organisation,id_organisation,id_standard)
organisation (id_organisation, organisation_name)
This is my query and it's giving me repetitive values:
select distinct a.question_text, d.organisation_name
from question a
inner join standard b on a.id_standard = b.id_standard
inner join organisation_standard c on b.id_standard= c.id_standard
inner join organisation d on c.id_organisation = d.id_organisation
where a.id_standard = 18;
How can I avoid the repetitive values?
What you need is a left join and not an inner join change the inner joins into left joins and you will get just one row:
select distinct
a.question_text, d.organisation_name
from
question a
left join
standard b ON a.id_standard = b.id_standard
left join
organisation_standard c ON b.id_standard = c.id_standard
left join
organisation d ON c.id_organisation = d.id_organisation
where
a.id_standard = 18
group by a.id_standard;
This diagram from another so answer gives the difference between the different joins

Correct Join Query for SQL Query

I currently have the following Query
SELECT * FROM tbl_Cars c
INNER JOIN tbl_Car_Parts cp ON c.Id = cp.Id
INNER JOIN tbl_Car_Factory cf ON cp.Id = cf.Id
However I have now realised that there are some Ids which are in the Cars Table which are then not in the Car Parts table so these are being omitted from my results while I want them included. I tried changing my INNER JOIN to a LEFT OUTER JOIN but it made no difference in the result set I am returned?
Use LEFT OUTER JOIN in both of the joins.
SELECT * FROM tbl_Cars c
LEFT OUTER JOIN tbl_Car_Parts cp ON c.Id = cp.Id
LEFT OUTER JOIN tbl_Car_Factory cf ON cp.Id = cf.Id
Otherwise the second INNER JOIN will invalidate your first LEFT OUTER JOIN for those records that does not have ID (does not join) in the tbl_Car_Parts table.
After a LEFT OUTER JOIN you may be only use again INNER JOIN if the table you are joining is not related with the previous ones that are joined using the LEFT OUTER JOIN.
LEFT JOIN should have definitely solved your problem, Not sure why it didnt work.
Just to be safe I used Left join on both the tables...
SELECT * FROM tbl_Cars c
LEFT JOIN tbl_Car_Parts cp ON c.Id = cp.Id
LEFT JOIN tbl_Car_Factory cf ON cp.Id = cf.Id

How does multiple "ON" in a JOIN statement works

I'm currently reading a query that I don't usually see in some other queries when joining tables.
SELECT
*
FROM table_1
RIGHT OUTER JOIN table_2
INNER JOIN table_3
ON table_2.some_id = table_3.some_id
RIGHT OUTER JOIN table_4
ON table_3.some_id = table_4.some_id
LEFT OUTER JOIN table_5
ON table_4.some_id = table_5.some_id
ON table_1.some_id = table_4.some_id
Please don't mind how those tables being joined. I just want to know how did that query works? Thank you in advance.
I think the SQL Server documentation captures what is happening better than MySQL. (Here is the documentation.)
This is a parsing issue, as Laurence has observed. You can understand what is by looking at the syntax diagram for the from statement. There is a recursive reference that most people never think about (including me). A joined table has the following syntax:
<joined_table> ::=
{
<table_source> <join_type> <table_source> ON <search_condition>
| <table_source> CROSS JOIN <table_source>
| left_table_source { CROSS | OUTER } APPLY right_table_source
| [ ( ] <joined_table> [ ) ]
}
The key here is the first piece, <table_source> <join_type> <table_source>. Well, guess what, a table_source can be a joined_table (as well as a bunch of other things). This means that the syntax:
A join B join C ON <condition1> ON <condition2>
Fits the grammar above and is interpreted as:
A join (B join C on <condition1>) ON <condition2>
That is, the expression B join C on <condition1> is treated as a "table_source".
My guess is that if both SQL Server and MySQL do it this way, then it is probably part of the standard. However, the standard is a bit harder to understand than SQL Server's syntax diagrams.
I think this is down to the way right outer join is evaluated:
Select
*
from
a
right outer join
b
inner join
c
on b.id = c.id
on a.id = b.id;
is evaluated as
Select
*
from
a
right outer join (
b
inner join
c
on b.id = c.id
)
on a.id = b.id;
Mixing left and right outer join is a path to madness.
The OP's query seems to be driven by a desire to exclude parenthesis, or derived tables. It is equivalent to:
Select
a.id ida,
b.id idb,
c.id idc,
d.id idd,
e.id ide
From
D
left outer join
A
on d.id = a.id
left outer join
E
on d.id = e.id
left outer join (
B
inner join
C
on b.id = c.id
)
on d.id = b.id;
Example SQLFiddle

Cartesian join with multple outer joins to common root

I have the following schema.
I can run two queries fairly simply
select * from booking_model_assignment
join booking_model on booking_model_assignment.booking_model_id = booking_model.id
left outer join axis_channel_mappings on bmi_id = axis_channel_mappings.assignment_id
left outer join axis_revenue_stream_mappings on bmi_id = axis_revenue_stream_mappings.assignment_id
which will give me all of the combinations of channel mappings and 'revenue_stream_mappings' which fit a booking model, with Null if there is one which only matches in one of the tables.
The other query
select * from axis_channel join axis_revenue_stream
Gives all of the possible combinations of channels and revenue streams.
What I would like is a query which will give all of the combinations, and the booking_model if that combination matches.
Any time I try to join or subquery I seem to get too many, or too few results. I think the issue is that I want the assignment_id to match across outer joins but only if there is an outer join.
The schema is laid out like this so it will be possible to add new axis and fit models to combinations, so if there is an easier way to achieve this I would be open to changing the schema.
EDIT
I have a partial solution based on Eggyal's answer but it is not extendable.
SELECT c.*, r.*, GROUP_CONCAT(a.bmi_id), GROUP_CONCAT(b.name) AS booking_models
FROM axis_channel c
CROSS JOIN axis_revenue_stream r
LEFT JOIN axis_channel_mappings cm ON cm.channel_id = c.id
LEFT JOIN axis_revenue_stream_mappings rm ON rm.revenue_stream_id = r.id
LEFT JOIN booking_model_assignment a ON (a.bmi_id = cm.assignment_id
AND a.bmi_id = rm.assignment_id)
OR (a.bmi_id = cm.assignment_id
AND rm.assignment_id IS NULL)
OR (cm.assignment_id IS NULL
AND a.bmi_id = cm.assignment_id)
LEFT JOIN booking_model b ON b.id = a.booking_model_id
GROUP BY c.id, r.id
But if I were to add more axes this query would grow way to cumbersome.
SELECT c.*, r.*, GROUP_CONCAT(b.name) AS booking_models
FROM axis_channel c
CROSS JOIN axis_revenue_stream r
LEFT JOIN axis_channel_mappings cm ON cm.channel_id = c.id
LEFT JOIN axis_revenue_stream_mappings rm ON rm.revenue_stream_id = r.id
LEFT JOIN booking_model_assignment a ON a.bmi_id = cm.assignment_id
AND a.bmi_id = rm.assignment_id
LEFT JOIN booking_model b ON b.id = a.booking_model_id
GROUP BY c.id, r.id