SQL request using join - mysql

I have 2 tables:
circuit(id_circuit, distance)
and
circuit_langue(id_circuit_language, #id_circuit, language, title).
if I do a join between circuit and circuit_langue, and it's possible that some objects from circuit don't have a circuit_langue,
what i have to do if I want to recuperate objects without circuit_langue ?

You most likely did INNER JOIN which shows only those records that have a matching row from both sides of the join (tables in this example).
You need a LEFT JOIN to view all circuits even if there is not circuit_langue row associated with it:
select *
from circuit c
left join circuit_langue cl on
c.id_circuit = cl.id_circuit
If you only need to display records that don't have a corresponding row in langue table you could add a WHERE condition to above query:
select *
from circuit c
left join circuit_langue cl on
c.id_circuit = cl.id_circuit
where cl.id_circuit is null

By default, the JOIN (INNER JOIN) recovers rows that match on both tables.
If you want to recover both the objects with and without a circuit_langue associated you can use a LEFT OUTER JOIN:
SELECT * FROM circuit c LEFT OUTER JOIN circuit_langue cl
ON c.id_circuit = cl.id_circuit

There are four main kinds of joins :
inner join (which is the default)
left outer join
right outer join
full outer join
You've used the INNER JOIN which only returns the matched values in both tables, while you actually need a LEFT OUTER JOIN which returns all rows from the left table, even if there are no matches in the right table.
For reference, the left table is the first one after the FROM keyword.
For further knowledge:
RIGHT OUTER JOIN : is exactly the opposite of LEFT OUTER JOIN.
FULL OUTER JOIN :returns rows when there is a match in either one of the tables.

Related

How to do multiple joins when some tables are empty

I am trying to append 'lookup data' to a main record text/description field so it looks something like this:
This is the Description Text
LookUpName1:
LookupValue1
LookupValueN
This worked fine with Inner Join like so
Select J.id, Concat('<b>LookUpName</b>:<br>',group_concat(F.LookUpValue SEPARATOR '<br>'))
from MainTable J Inner Join
LookUpTable L Inner Join
LookUpValuesTable F
On J.ID = L.JobID and F.ID = L.FilterID
Group by J.ID
However my goal is to add append multiple Lookup Tables and if I add them to this as Inner Joins I naturally just get those record where both/all the LookupTables have records.
On the other hand when I tried Join or Left Join I got an error on the Group by J.ID.
My goal is to append any of the existing Lookup Table values to all of the Description. Right now all I can achieve is returning appended descriptions which have ALL of the Lookup table values.
Your query would work if the on clauses were in the "right" place:
select J.id,
Concat('<b>LookUpName</b>:<br>', group_concat(F.LookUpValue separator '<br>'))
from MainTable J left join
LookUpTable L
on J.ID = L.JobID left join
LookUpValuesTable F
on F.ID = L.FilterID
group by J.ID;
The problem with your query is a MySQL (mis)feature. The on clause is optional for an inner join. Don't ask me why the MySQL designers thought inner join and cross join should be syntactically equivalent. Every other database requires an on clause for an inner join. It is easy enough to express a cross join using on 1=1.
However, the on clause is required for the left join, so when you switch to a left join, the compiler has a problem with the unorthodox syntax. The real problem is a missing on clause; this just happens to show up as "I wasn't expecting a group by yet." Using more traditional syntax with each join followed by an on should fix the problem.

Issue SQL join query

I am getting issues with the below SQL query, unable to fetch the desired result
SELECT
C.Department__c
,C.Email
,R.AcctID__c
,C.ContactID__c
,R.TransactionDueDate
,R.PubNbr__c
FROM RenewalNotificationProgramDE R
LEFT JOIN ContactNewDE C
ON R.AcctID__c = C.AcctID__c
The idea is to join all the AccountID(AcctID__c) in RenewalNotificationProgramDE table to the corresponding contacts in ContactNewDE table. AccountID is the foreign key in the ContactNewDE table. I am usig Innerjoin in my query as I want all AccountID to map with their corresponding contacts in ContactNewDE.
Just replace LEFT JOIN by INNER JOIN to get all AccountID with their corresponding contacts :-
Use below query :-
SELECT
C.Department__c
,C.Email
,R.AcctID__c
,C.ContactID__c
,R.TransactionDueDate
,R.PubNbr__c
FROM RenewalNotificationProgramDE R
INNER JOIN ContactNewDE C
ON R.AcctID__c = C.AcctID__c
You have used LEFT JOIN in your query, which you need to change it to INNER JOIN. I think you would better to notice the below notes about differences between left and inner joins:
INNER JOIN: Returns all rows when there is at least one match in BOTH
tables
LEFT JOIN: Return all rows from the left table, and the
matched rows from the right table

How to Convert Left Outer JOIN Query to Subset Query

how to convert this left outer join query to subset query
select
j.*, concat(d.Name, ', ', d.Gelar) as DSN,
prg.Nama_Indonesia as PRG,
kl.Kelas as kls,
kl.Sesi as ssi
from
jadwal j left outer join
dosen d on j.IDDosen=d.ID left outer join
kelas kl on j.Kelas=kl.ID left outer join
program prg on j.Program=prg.Kode left outer join
jabatanorganisasi jo on d.JabatanOrganisasi=jo.Kode left outer join
tahun t on j.tahun=t.id
order by
d.Name, prg.Nama_Indonesia, kl.Sesi, kl.Kelas;
please help
give me axample
For the first query you will be having rows, since all of the joins are LEFT JOIN, so atleast all entries from table jadwal will be there in output.
But on the other query you are doing selection using conditions(works like INNER JOIN), if the condition not satisfies there wont be any result-set.Thats why you are not getting any outputs.
There is no data with these conditions.Please check data
where
j.IDDosen=d.ID and
j.kelas=kl.ID and
j.program=prg.kode and
j.tahun=t.id AND
d.JabatanOrganisasi=jo.kode
Hope this helps
In the first query, you are using left joins (which means if there's no match between from table and the joining tables it would retrieve all the results from the from table), and in the second query you are using inner joins.
You can take a look on this What is the difference between "INNER JOIN" and "OUTER JOIN"?

Full Outer Joins in MS Access

My situation: I have a central PI table (patient information) which stores every single patient in the database. Then I have a few other tables (ex. vital signs, self report scores, etc.). The problem is, not every patient completes measures in every table. I.e., a patient might have an entry in the vital signs table but not in the self report table. How can I run a query where it shows me ALL patients in the PI table and their corresponding vitals and SR data if it exists instead of restricting the query to only show me patients that have records in ALL three of those tables?
I'm unclear why you want a FULL OUTER JOIN.
You have a PI table which includes a row for every patient. You have another table like SR data which contains the self-reported data for those patients. Assuming they have a common key ... perhaps patient_id ... a LEFT JOIN will give you a row for each patient regardless of whether there is any SR Data available for that patient:
SELECT *
FROM
[PI table] AS pi
LEFT OUTER JOIN [SR Data] AS sr
ON pi.patient_id = sr.patient_id;
Note Access will be happy with either LEFT OUTER JOIN or just LEFT JOIN there. OUTER is not needed, but Access won't object if you include it.
So I think you only need a LEFT JOIN. You would only need (the equivalent of) a FULL OUTER JOIN if the SR Data includes rows which don't match to any of the existing patients in the PI table and you want those unmatched rows included in the query result. But you didn't indicate that applies to your question, so I'm ruling it out unless you tell us otherwise.
You can LEFT JOIN another table to the first query ...
SELECT *
FROM
([PI table] AS pi
LEFT OUTER JOIN [SR Data] AS sr
ON pi.patient_id = sr.patient_id)
LEFT JOIN [Vital Signs] AS v
ON pi.patient_id = v.patient_id;
... and extend from there for additional tables as needed. If you use the Access query designer to set up your joins, it will add in parentheses correctly as the db engine demands for any query which includes more than one join.
Access (unfortunately) does not support OUTER JOIN. What it does is INNER, LEFT and RIGHT JOINS.
INNER JOIN - Gives you only the information common to two tables.
RIGHT JOIN - Gives all information that are common to the two table and information that are not matched form the table that is on the RIGHT to the JOIN statement.
LEFT JOIN - Gives all information that are common to the two table and information that are not matched form the table that is on the LEFT to the JOIN statement.
OUTER JOIN - is the UNION of RIGHT JOIN and LEFT JOIN.
So as expected, you just have to perform two Queries that perform a JOIN in both directions and then marry them using a UNION. This is a long process, but is the only way !
SELECT * FROM
(SELECT table1.FieldName1, table2.FieldName2
FROM table1 RIGHT JOIN table2 ON table1.ID = table2.ID
UNION
SELECT table1.FieldName1, table2.FieldName2
FROM table1 LEFT JOIN table2 ON table1.ID = table2.ID)

MySQL getting data from 3 tables which are connected by mapping tables

I have the following database example:
The example is pretty much self-explanatory: There are lessons held by teachers at defined time periods (time_start, time_end) each time period -> lesson connection has its own max_students number.
I know want to list all lessons with all information of the 3 tables (and the max_students). I would do it like that (I heard, that joining table like that is the fastest way):
SELECT * FROM lesson, teacher, time, teacher_has_lesson, time_has_lesson
WHERE lesson.lesson_id = teacher_has_lesson.lesson_lesson_id
AND teacher.teacher_id = teacher_has_lesson.teacher_teacher_id
AND lesson.lesson_id = time_has_lesson.lesson_lesson_id
AND time.time_id = time_has_lesson.time_time_id
1.) Is this a good solution if you just want to join 3 tables or are there better ones?
2.) This SQL call will get me only lessons, that have a teacher and a time. I also want to display lessons, that are in the database, but dont have a teacher or time yet. How can I do that?
There's an alternative way of writing this using join syntax. What you have is equivalent to an inner join, where you only see rows where there are matches:
select
*
from
lesson l
inner join
teacher_has_lesson tl
on l.lession_id = tl.lesson_lesson_id
inner join
teacher t
on tl.teacher_teacher_id = t.teacher_d
inner join
time_has_lesson tml
on l.lesson_id = tml.lesson_lesson_id
inner join
time tm
on tml.time_time_id = tm.time_ud
There's another type of join called outer join, where all the rows from one table are shown, and null values supplied if there are no matching values in the other table. It comes in two or three variants. left outer join shows all rows from the first table. right outer join shows all rows from the second table. full outer join shows all rows from both tables. So, for your second query you could use:
select
*
from
lesson l
left outer join
teacher_has_lesson tl
on l.lession_id = tl.lesson_lesson_id
left outer join
teacher t
on tl.teacher_teacher_id = t.teacher_d
left outer join
time_has_lesson tml
on l.lesson_id = tml.lesson_lesson_id
left outer join
time tm
on tml.time_time_id = tm.time_ud