Multiple full joins in one query on multiple tables - sql

I have a database with multiple tables, I wish to show all contents from every table with one query (that I will use later for a research in the database).
view of the database
I've tried with two tables
[SELECT
reception.num_courrier, reception.date_recep, reception.expediteur, reception.objet,
lect_prefet.date_lect_prefet, lect_prefet.instructions, lect_prefet.caractere
FROM
reception
FULL JOIN
lect_prefet ON reception.num_courrier = lect_prefet.num_courrier][2]
but it returns an error.
I'm using 10.4.14-MariaDB version.
full join query error

One method uses multiple left joins, starting with all available ids:
SELECT *
FROM (SELECT r.num_courrier
FROM reception r
UNION -- on purpose to remove duplicate
SELECT l.num_courrier
FROM lect_prefet l
) c LEFT JOIN
reception r
USING (num_courrier) LEFT JOIN
lect_prefet l
USING (num_courrier);
This approach easily generalizes to more tables using the same key for the JOIN.

Please try the following:
SELECT * FROM reception r
LEFT OUTER JOIN lect_prefet lp ON lp.num_courrier = r.num_courrier
LEFT OUTER JOIN lect_sg ls ON ls.num_courrier = r.num_courrier
LEFT OUTER JOIN ad ad ON ad.num_courrier = r.num_courrier
LEFT OUTER JOIN agt agt ON agt.num_courrier = r.num_courrier
If the above doesn't work, it would be great if you can provide an SQLFiddle example so that others can try on a live schema.

Thank you all, you really helped me, this is what I expected, folowing the answer of #Gordon Linoff[ adding some rows] Thank you
SELECT * FROM (
SELECT r.num_courrier FROM reception r UNION
SELECT l.num_courrier FROM lect_prefet l UNION
SELECT s.num_courrier FROM lect_sg s UNION
SELECT g.num_courrier FROM agt g UNION
SELECT d.num_courrier FROM ad d ) c
LEFT JOIN reception r USING (num_courrier)
LEFT JOIN lect_prefet l USING (num_courrier)
LEFT JOIN lect_sg s USING (num_courrier)
LEFT JOIN agt g USING (num_courrier)
LEFT JOIN ad d USING (num_courrier);
Expected
Answer

Related

use Inner Join in SQL

I want to join two tables and then I want to join this result with another table
but it doesn't work
select * from
(
(select SeId,FLName,Company from Sellers) s
inner join
(select SeId,BIId from BuyInvoices) b
on s.SeId=b.SeId
) Y
inner join
(select * from BuyPayments) X
on Y.BIId=X.BIId
thanks
In most databases, your syntax isn't going to work. Although parentheses are allowed in the FROM clause, they don't get their own table aliases.
You can simplify the JOIN. This is a simpler way to write the logic:
select s.SeId, s.FLName, s.Company, bp.*
from Sellers s inner join
BuyInvoices b
on s.SeId = b.SeId inner join
BuyPayments bp
on bp.BIId = b.BIId;

SQL: Proper JOIN Protocol

I have the following tables with the following attributes:
Op(OpNo, OpName, Date)
OpConvert(OpNo, M_OpNo, Source_ID, Date)
Source(Source_ID, Source_Name, Date)
Fleet(OpNo, S_No, Date)
I have the current multiple JOIN query which gives me the results that I want:
SELECT O.OpNo AS Op_NO, O.OpName, O.Date AS Date_Entered, C.*
FROM Op O
LEFT OUTER JOIN OpConvert C
ON O.OpNo = C.OpNo
LEFT OUTER JOIN Source D
ON C.Source_ID = D.Source_ID
WHERE C.OpNo IS NOT NULL
The problem is this. I need to join the Fleet table on the previous multiple JOIN statement to attach the relevant S_No to the multiple JOIN table. Would I still be able to accomplish this using a LEFT OUTER JOIN or would I have to use a different JOIN statement? Also, which table would I JOIN on?
Please note that I am only familiar with LEFT OUTER JOINS.
Thanks.
I guess in your case you could use INNER JOIN or LEFT JOIN (which is the same thing as LEFT OUTER JOIN in SQL Server.
INNER JOIN means that it will only return records from other tables only if there are corresponding records (based on the join condition) in the Fleet table.
LEFT JOIN means that it will return records from other tables even if there are no corresponding records (based on the join condition) in the Fleet table. All columns from Fleet will return NULL in this case.
As for which table to join, you should really join the table that makes more logical sense based on your data structure.
Yes, you can use all tables mentioned before in your join conditions. Actually, JOINS (no matter of INNER, LEFT OUTER, RIGHT OUTER, CROSS, FULL OUTER or whatever) are left- associative, i. e. they are implicitly evaluated as if they would have been included in parentheses from the left as follows:
FROM ( ( ( Op O
LEFT OUTER JOIN OpConvert C
ON O.OpNo = C.OpNo
)
LEFT OUTER JOIN Source D
ON C.Source_ID = D.Source_ID
)
LEFT OUTER JOIN Fleet
ON ...
)
This is similar to how + or - would implicitly use parentheses, i. e.
2 + 3 - 4 - 5
is evaluated as
(((2 + 3) - 4) - 5)
By the way: If you use C.OpNo IS NOT NULL, then the LEFT OUTER JOIN Source D is treated as if it were an INNER JOIN, as you are explicitly removing all the "OUTER" rows.

Get ID from another table through a table

Sorry for Title, don't know how to explain.
Ok so I want to see if any protocol (PTC_ID) is linked to an Audit (AUD_ID), in the picture you can see there is 3 tables and each one has a value of the other.
I though of using inner join all 3 tables with the ON , ON ADA_PTCID = PTC_ID etc. and if a audit is linked with a PTC then display year?
Select AUD_YEAR
From AUD_Table at
Inner Join ADA_TABLE ad
ON at.AUD_ID = ad.ADA_AUD_ID
Inner Join PTC_TABLE pt
ON pt.PTC_ID=ad.ADA_PTCID
try
select
ptc.ptc_name,
aud.aud_year
from
ptc_table ptc
inner join
ada_table ada
on
ada.ada_ptcid=ptc.ptc_id
inner join
aud_table aud
on
aud.aud_id=ada.ada_aud_id
Something like this?
select
aud.year,ptc.name
from ada
inner join aud on ada.aud_id = aud.aud_id
inner join ptc on ada.ptc_id = ptc.ptc_id

t-sql query that returns missing records

I have a query (ContactFormTypesRequired) that returns ContactID and FormTypeID utilizing related tables that are not shown below. This is a list of FormTypes that each Contact should have related to it as a Form.
I need a query that returns Contacts that do not have one or more related forms of the FormTypes specified in the above query.
I've tried a left outer join from Form to ContactsFormTypesRequired on FormTypeID, but the results don't take into account FormTypes that each specific Contact should have.
Please let me know if you have any questions.
Thank you in advance for any suggestions.
I am writing the query this way. This first starts with your query to get needed forms as a CTE, then cross joins them to Contacts to get every needed combination, before left joining to the actual forms.
with NeededForms (<yourqueryhere>)
select distinct c.*
from Contact c cross join
NeededForms nf left outer join
Form F
on nf.FormTypeId = f.FormTypeId left outer join
ContactForm cf
on c.ContactId = cf.ContactId and
f.FormId = cf.FormId
where cf.FormId is null
I'm doing it this way, so you can answer the query of what forms are missing with a very similar query:
with NeededForms (<yourqueryhere>)
select c.*, nf.FormTypeId
from Contact c cross join
NeededForms nf left outer join
Form F
on nf.FormTypeId = f.FormTypeId left outer join
ContactForm cf
on c.ContactId = cf.ContactId and
f.FormId = cf.FormId
where cf.FormId is null
Try this simple query using NOT IN Cluase:
SELECT * FROM Contact
WHERE ContactID IN
(SELECT ContactID FROM ContactForm
INNER JOIN FORM ON ContactForm.FormID=Form.FormID
WHERE FormTypeID=#FormTypeID)
I created ContactFormTypeExist:
SELECT DISTINCT Contact.ContactID, Form.FormTypeID
FROM Contact
INNER JOIN ContactForm
ON Contact.ContactID = ContactForm.ContactID
INNER JOIN Form
ON ContactForm.FormID = Form.FormID
Then joined ContactFormTypesRequired described in the question above to ContactFormTypeExist with outer join to give me the ConactIDs that are missing related FormTypeIDs:
SELECT ContactFormTypesRequired.ConactID
FROM ContactFormTypeExist
RIGHT JOIN ContactFormTypesRequired
ON (ContactFormTypeExist.FormTypeID = ContactFormTypesRequired.FormTypeID)
AND (ContactFormTypeExist.ConactID = ContactFormTypesRequired.ConactID)
WHERE (((ContactFormTypeExist.ConactID) Is Null));
This returns all the ContactID for Contacts missing FormTypes required by their ContactType.

Sybase 12 LEFT JOIN Performance issue for CrystalReports

I am trying to optimize a Crystal Report that is used very frequently here. I succeeded to optimize lots of queries but I still have one last bottleneck: This is the main query, generated from the report.
SELECT
A.*,
B.*,
C.*,
D.*,
E."N",
F."N",
G."N"
FROM
A
LEFT OUTER JOIN B ON
A."PK" = B."FK"
LEFT OUTER JOIN C ON
A."PK" = C."FK"
LEFT OUTER JOIN D ON
A."FK" = D."PK"
LEFT OUTER JOIN E ON
A."PK" = E."FK"
LEFT OUTER JOIN F ON
A."PK" = F."FK"
LEFT OUTER JOIN G ON
A."PK" = G."FK"
WHERE A.PK = ####
A,B,C and D are tables. E,F,G are simple views.
As you see, the report generated multiple LEFT JOINS. This query takes 2.28 seconds to complete (From the Plan Viewer stats). I identified three joins that seem problematic. If I remove E,F,G from the query, it becomes almost instant (0.0009s from the same stats)
SELECT
A.*,
B.*,
C.*,
D.*
FROM
A
LEFT OUTER JOIN B ON
A."PK" = B."FK"
LEFT OUTER JOIN C ON
A."PK" = C."FK"
LEFT OUTER JOIN D ON
A."FK" = D."PK"
WHERE A.PK = ####
I tought it might be the views that are slow, but if I do for example ...
SELECT *
FROM E
WHERE E.FK = ####
... it is also almost instant (0.0009s)
Tables all have indexes on PKs-FKs.
Views E,F,G all return one or no row with [FK|N] as columns, so the resulting column is NULL or a number.
Do you know how I could make this query fast?
PS: If I replace LEFT OUTER JOINS by INNER JOINS the main query becomes fast... :-/
Or trying to split this query into multiple queries on the report would be a better solution?
Thank you!
I would create functions for the lookup against E, F and G instead of joining them.
That way there is little chance the optimiser gets confused and tries to do stupid things.
SELECT
A.*,
B.*,
C.*,
D.*,
GET_E(A."PK"),
GET_F(A."PK"),
GET_G(A."PK")
FROM
A
LEFT OUTER JOIN B ON
A."PK" = B."FK"
LEFT OUTER JOIN C ON
A."PK" = C."FK"
LEFT OUTER JOIN D ON
A."FK" = D."PK"
WHERE A.PK = ####
The problem is probably because you are creating a huge cartesian product of 5 tables all joined to A in some way (A and D will only contribute one record to the product). Having such a big cartesian product will consume quite a bit of memory internally in Sybase. It is likely that your query is just wrong.