4 Tables Joining in SQL - sql

I have some preps/views which im using in my final select clause in the following way :
select .......
from gr
full outer join go
on gr.ART_CONC=go.ART_CONC and
gr.pt=go.pt and
gr.p_act=go.p_act and
gr.month_id=go.month_id and
gr.art_desc=go.art_desc
Now i want to also include the following in my select clause, but im confused how the syntax and join would really go
sim ab join prep1
on ab.fp_num3 = article_num AND
substr(ab.fp_num2,-2,2) = substr(pt10,-2,2)
where fp_data_kind='SEC PFE_ND_GO'
and fp_data_valid_from between to_date(:par_date_from, 'YYYY.MM.DD HH24:MI:SS') and to_date(:par_date_to, 'YYYY.MM.DD HH24:MI:SS')
Note : sim, prep1,gr and go are 4 tables/preps that already exist.
Thanks in Advance !

In this, table1/2/3/4 are your tables. join_val's are the values you are joining on. I did not fully understand your question or what you wanted so this one way to go about doing 4 joins.
select t1.something1
,t1.something2
,t1.something3
,t2.something1
,t2.something2
,t2.something3
,t3.something1
,t3.something2
,t3.something3
,t4.something1
,t4.something2
,t4.something3
from table1 t1
full outer join table2 t2
on t1.join_val = t2.join_val
......
full outer join table3 t3
on t1.join_val = t3.join_val
......
full outer join table4 t4
on t.join_val = t3.join_val

Related

Oracle join optimization

I have the following SQL query:
select dres.colA,
dres.colP,
dres.ID,
dre.ID,
dre.colED,
dre.VID,
vpp.VID,
vpp.colDESC
from table1 dres
left join table2 dre on dres.ID = dre.ID
left join table3 vpp on vpp.VID = dre.VID
where dre.START_TIME >= date '2017-01-01';
Do you have any suggestion how the query can work better (or should look)?
Something like:
...where dres.ID in (select * from table2
where VID in (select * from table3))....
First, your where clause changes the outer joins to inner joins. So, start by writing the query as:
select dres.colA, dres.colP, dres.ID,
dre.ID, dre.colED, dre.VID,
vpp.VID, vpp.colDESC
from table1 dres join
table2 dre
on dres.ID = dre.ID join
table3 vpp
on vpp.VID = dre.VID
where dre.START_TIME >= date '2017-01-01';
The place to start is with indexes on table2(id, vid, start_time, colED) and table3(vid, colDESC).
It is possible that an alternative indexing strategy would work: table2(start_time, id, vid, colED). This would allow the where clause to use the index. But that particular where clause may not be highly selective.

SQL Simple Query From Multiple Tables

I would appreciate if anyone can give me a hand with this question
I have 4 SQL tables. Open, High, Low and Close.
Each have 2 columns called [Date],[Price].
The dates are the same - but Price is a number and is different.
How can we make a query where the results are as follows
[Date],[Open.Price],[High.Price],[Low.Price],[Close.Price]
SELECT Open_table.date,Open_table.Price,High_table.Price,low_table.Price,
Close_table.Price
FROM Open_table
JOIN High_table ON Open_table.date = High_table.date
JOIN low_table ON Open_table.date = low_table.date
JOIN Close_table ON Open_table.date = Close_table.date
You could try joining on date:
SELECT t1.[Date],
t1.[Price] AS [Open.Price],
t2.[Price] AS [High.Price],
t3.[Price] AS [Low.Price],
t4.[Price] AS [Close.Price]
FROM Open t1
INNER JOIN High t2
ON t1.[Date] = t2.[Date]
INNER JOIN Low t3
ON t2.[Date] = t3.[Date]
INNER JOIN Close t4
ON t3.[Date] = t4.[Date]
I found another way of doing so after I posted this question
SELECT
EuropeOpen.[Date],EuropeOpen.[OCDO LN],EuropeHigh.[Date],EuropeHigh.[OCDO LN],EuropeLow.[Date],EuropeLow.[OCDO LN],
EuropeClose.[Date],EuropeClose.[OCDO LN]
FROM EuropeOpen,EuropeHigh,EuropeLow,EuropeClose
// In case you need any conditions
WHERE....

Improving performance: Very Slow Oracle SQL Join

I am a newbie in SQL querying and I am spending 3hrs to get the whole result of joining 2 queries.
I have focused on using left joins and avoided using subqueries on the select statement after researching. However it is still extremely slow. I have no close friends who know sql enough to explain whats wrong or what I approach I should take.
I am also new here so if this question is not allowed please inform me and I will remove it immediately.
This is the structure of the query...
The first query will get the member details.
The second query will get the transaction details.
The relationship is,
one product has many sub-plans which has many members.
One product also has many transactions which is made on a per product basis.
I am required to show all transactions and duplicate each line for each member.
I joined the queries using the product primary key.
Prior to joining, I have tested both individual queries and they turned out fine. Only 1-2 secs and I get the result.
But joining the two, I end up with 3 hrs of waiting.
SELECT
MPPFF.N_DX,
MPPFF.PM_A_P,
MPPFF.FEE1,
MPPFF.FEE2,
MPPFF.FEE3,
MPPFF.FEE4,
MPPFF.FEE11,
MPPFF.FEE12,
MPPFF.FEE5,
MPPFF.N_NO,
MPPFF.SETN_DX,
MPPFF.PRIME_NO,
MPPFF.SECN_NO,
MPPFF.COMM_A,
MPPFF.TYX_NO,
MPPFF.P_NAME,
MPPFF.B_BFX,
MPPFF.B_FM,
MPPFF.B_TO,
MPPFF.BB_NAME_P,
MPPFF.BB_NAME_S,
MPPFF.REVERSE_BFX,
MPPFF.TYX_REF_NO,
MPPFF.BB_NO_AX,
MPPFF.BB_NAME_AX,
MPPFF.DXC,
MPPFF.ST,
MPPFF.DAY,
MPPFF.CE_D_PRODUCT,
MPPFF.CE_H,
MPPFF.AS_C_E,
MPPFF.BCH,
MPPFF.RCPY_NO,
MPPFF.RE_BFX,
MPPFF.A_END,
MPPFF.PLACE,
MPPFF.MEMB_DX,
MPPFF.MBR_NO,
MPPFF.MBR_TR_BFX,
MPPFF.CE_D_TERM_CE,
MPPFF.MEMBER_AS,
MPPFF.C_USER,
MPPFF.C_BFX,
MPPFF.U_USER,
MPPFF.U_BFX
FROM (
SELECT
FF.N_DX,
FF.PM_A_P,
FF.FEE1,
FF.FEE2,
FF.FEE3,
FF.FEE4,
FF.FEE11,
FF.FEE12,
FF.FEE5,
FF.N_NO,
FF.SETN_DX,
FF.PRIME_NO,
FF.SECN_NO,
FF.COMM_A,
FF.TYX_NO,
FF.P_NAME,
FF.B_BFX,
FF.B_FM,
FF.B_TO,
FF.BB_NAME_P,
FF.BB_NAME_S,
FF.REVERSE_BFX,
FF.TYX_REF_NO,
FF.BB_NO_AX,
FF.BB_NAME_AX,
FF.DXC,
FF.ST,
FF.DAY,
FF.CE_D_PRODUCT,
FF.CE_H,
FF.AS_C_E,
FF.RCPY_NO,
FF.RE_BFX,
FF.A_END,
FF.BCH,
MPP.MBR_NO,
MPP.MBR_TR_BFX,
MPP.CE_D_TERM_CE,
MPP.C_USER,
MPP.C_BFX,
MPP.U_USER,
MPP.U_BFX,
MPP.PLACE,
MPP.MEMBER_AS,
MPP.TYX_DX,
MPP.AS_DX,
MPP.PRODUCT,
MPP.POPL_DX,
MPP.MEMB_DX,
FF.TYX_DX
FROM (
SELECT
MBR.MEMB_DX,
MBR.MBR_NO,
MBR.MBR_TR_BFX,
MBR.CE_D_TERM_CE,
MBR.C_USER,
MBR.C_BFX,
MBR.U_USER,
MBR.U_BFX,
MPP.PLACE,
MPP.MEMBER_AS,
MPP.TYX_DX,
MPP.AS_DX,
MPP.PRODUCT,
MPP.POPL_DX
FROM (
SELECT
MPP.PLACE,
MPP.MEMBER_AS,
MPP.TYX_DX,
MPP.AS_DX,
MPP.PRODUCT,
MPP.POPL_DX,
MMP.MEMB_DX
FROM(
SELECT
MPP.PLACE,
MPP.TYX_AS_DXC MEMBER_AS,
MPP.TYX_DX,
MPP.AS_DX,
MPP.POPL_DX,
RPT.PRODUCT
FROM
TABLE1 MPP
LEFT JOIN (
SELECT
SUBSTR(CE_D_PRODUCT,9) PRODUCT,
AS_DX
FROM
TABLE6 RPT,
TABLE7 PP
WHERE
PP.PRTY_DX = RPT.PRTY_DX
) RPT
ON MPP.AS_DX = RPT.AS_DX
) MPP
LEFT JOIN (
SELECT
POPL_DX,
MEMB_DX
FROM
TABLE4
)MMP
ON MPP.POPL_DX=MMP.POPL_DX
) MPP,
(
SELECT
MBR.MEMB_DX,
MBR.MBR_NO,
MBR.TERM_BFX MBR_TR_BFX,
MBR.CE_D_TERM_CE,
MBR.C_USER,
MBR.C_BFX,
MBR.U_USER,
MBR.U_BFX
FROM
TABLE8 MBR
) MBR
WHERE
MPP.MEMB_DX = MBR.MEMB_DX
) MPP
INNER JOIN
(
SELECT
FF.N_DX,
ROUND(CB.FEE5 * FF.RATE,2) PM_A_P,
CB.FEE1,
CB.FEE2,
CB.FEE3,
CB.FEE4,
CB.FEE11,
CB.FEE12,
CB.FEE5,
FF.N_NO,
FF.SETN_DX,
FF.PRIME_NO,
FF.SECN_NO,
FF.COMM_A,
FF.TYX_NO,
FF.P_NAME_1||', '||FF.P_NAME_2||' '||FF.P_NAME_3 P_NAME,
FF.B_BFX,
FF.B_FM,
FF.B_TO,
FF.BB_NAME_1_P||', '||FF.BB_NAME_2_P BB_NAME_P,
FF.BB_NAME_1_S||', '||FF.BB_NAME_2_S BB_NAME_S,
CB.REVERSE_BFX,
FF.TYX_REF_NO,
FF.BB_NO_AX,
FF.BB_NAME_1_AX||' '|| FF.BB_NAME_2_AX BB_NAME_AX,
CASE
WHEN FF.CE_D_ST IN ('A', 'B', 'C') THEN 'AC'
WHEN FF.DAY >1 THEN 'NEW'
ELSE 'AB'
END DXC,
FF.CE_D_ST ST,
FF.DAY,
FF.CE_D_PRODUCT,
FF.CE_D_COMP CE_H,
FF.AS_C AS_C_E,
FF.RCPY_NO,
FF.RE_BFX,
ROUND(CB.A_S,2) A_END,
FF.TYX_DX,
MP.BCH
FROM
TABLE2 CB,
TABLE3 FF
LEFT JOIN (
SELECT
SUBSTR(CE_D_BCH_O,13) BCH,
TYX_DX
FROM
TABLE5 MP
)MP
ON MP.TYX_DX = FF.TYX_DX
WHERE
FF.SETN_DX = CB.SETN_DX AND
EXTRACT( YEAR FROM FF.EFF_BFX) >=2013
) FF
ON MPP.TYX_DX = FF.TYX_DX
)MPPFF
;
Use ROWNUM to prevent optimizer transformations from degrading the performance.
You are encountering a common problem - two queries run fast separately but run slow when put together. Oracle does not have to run the queries in the order they are written. It can merge views, push predicates around, and generally completely re-write the query to run in a different order. Normally this is a great thing because you don't want to have to worry about which physical order to join tables. But sometimes Oracle applies the wrong transformations and the results are disastrous.
There are two ways to solve these problems.
Look at table structures, the statements, the execution plans, SQL monitoring or traces, statistics, etc. Try to find out which operation is slow, and why (use cardinality as your guide), and then try to fix it. This process can easily take hours, maybe even days, but it's the best way to learn.
Stop the optimizer from combining the queries with a simple trick. There are a few ways to do this but in my experience the simplest way is to add the pseudo-column ROWNUM to any inline view that you do not want transformed. ROWNUM is a special column that tells Oracle "this query block must be returned in a specific way, don't do anything to it".
Change this:
--This is slow:
select ...
from
(
--This is fast:
select ...
) inline_view1
join
(
--This is fast:
select ...
) inline_view2
on ...
to this:
--Now this is fast.
select ...
from
(
--This is fast:
select rownum /*add rownum to prevent slow transformations*/, ...
) inline_view1
join
(
--This is fast:
select rownum /*add rownum to prevent slow transformations*/, ...
) inline_view2
on ...
In your code I believe the two inline views to modify would be the outer-most MPP and FF.
On a side note, I disagree with with some of the other comments and answers.
A CTE will not help here since none of the tables are used twice.
You don't always need to know a million details about the query to tune it. Unless you have the time and want to improve your skills.
I think your over-all query structure is good. You are on the right path to building great SQL statements. Inline views are the key to writing SQL - build small units of code, combine them in simple steps, repeat. Putting all the tables together in one massive join is a recipe for spaghetti code. Although I agree with others that you should avoid the old-fashioned join syntax. And the query would really benefit from some comments and more meaningful names. And don't feel afraid to put all the select list items on one line. Having a 500-column line isn't ideal, but you want to focus on the joins, not the simple list of columns.
Your query is almost unreadable, because of all the nesting. And you are mixing pre 1992 style joins with current join syntax. Don't use the outdated comma-separated join syntax. It is prone to errors. All your outer-joins are void, because at some point you will always have criteria that dismisses outer-joined records, such as when inner-joining table8 on the outer-joined table4's memb_dx.
Your query seems to translate to
select
<several fields from the tables>
from table1 mpp
join table6 rpt on rpt.as_dx = mpp.as_dx
join table7 pp on pp.prty_dx = rpt.prty_dx
join table4 mmp on mmp.popl_dx = mpp.popl_dx
join table8 mbr on mpp.memb_dx = mmp.memb_dx
join table3 ff on ff.tyx_dx = mpp.tyx_dx and extract(year from ff.eff_bfx) >= 2013
join table2 cb on ff.setn_dx = cb.setn_dx
left join table5 mp on mp.tyx_dx = ff.tyx_dx;
and maybe you want it to be
select
<several fields from the tables>
from table1 mpp
left join table6 rpt on rpt.as_dx = mpp.as_dx
left join table7 pp on pp.prty_dx = rpt.prty_dx
left join table4 mmp on mmp.popl_dx = mpp.popl_dx
left join table8 mbr on mpp.memb_dx = mmp.memb_dx
join table3 ff on ff.tyx_dx = mpp.tyx_dx and extract(year from ff.eff_bfx) >= 2013
join table2 cb on ff.setn_dx = cb.setn_dx
left join table5 mp on mp.tyx_dx = ff.tyx_dx;
instead or something along the lines. Get rid of all the nesting and stay with a clear and easy to read from clause.
One thing others haven't mentioned is the use of
EXTRACT( YEAR FROM FF.EFF_BFX) >=2013
This applies the EXTRACT function to every row selected from TABLE3 (I believe that's what FF refers to at this point in the query). I suggest replacing the above with
FF.EFF_BFX >= TO_DATE('01-JAN-2013', 'DD-MON-YYYY')
or something similar. This requires only a single call to TO_DATE to generate the date constant, which is then compared directly to FF.EFF_BFX, which appears to be a column of type DATE.
This query also uses the same table alias (e.g. FF, MPP, etc) multiple times for different entities in different contexts. In my opinion this is bad practice, and I suggest you rework your query to use a unique alias for each entity, which will make the query easier to understand.
As others have mentioned, getting rid of the pre-1992 joins in the WHERE clause would also help clarify what's going on, as would getting rid of the long column lists. A couple of the subqueries could be eliminated as well which would make the query cleaner and clearer.
After dealing with all the above I get the following:
SELECT *
FROM (SELECT *
FROM TABLE1 MPP
LEFT OUTER JOIN (SELECT SUBSTR(CE_D_PRODUCT, 9) PRODUCT,
AS_DX
FROM TABLE6 RPT
INNER JOIN TABLE7 PP
ON PP.PRTY_DX = RPT.PRTY_DX) RPT
ON MPP.AS_DX = RPT.AS_DX
LEFT OUTER JOIN TABLE4 MMP
ON MPP.POPL_DX = MMP.POPL_DX) MPP
INNER JOIN TABLE8 MBR
ON MPP.MEMB_DX = MBR.MEMB_DX
INNER JOIN (SELECT FF.*,
CB.*,
ROUND(CB.FEE5 * FF.RATE,2) PM_A_P,
FF.P_NAME_1 || ', ' || FF.P_NAME_2 || ' ' || FF.P_NAME_3 P_NAME,
FF.BB_NAME_1_P || ', ' || FF.BB_NAME_2_P BB_NAME_P,
FF.BB_NAME_1_S || ', ' || FF.BB_NAME_2_S BB_NAME_S,
FF.BB_NAME_1_AX || ' ' || FF.BB_NAME_2_AX BB_NAME_AX,
CASE
WHEN FF.CE_D_ST IN ('A', 'B', 'C') THEN 'AC'
WHEN FF.DAY > 1 THEN 'NEW'
ELSE 'AB'
END DXC,
ROUND(CB.A_S,2) A_END,
SUBSTR(MP.CE_D_BCH_O, 13) AS BCH
FROM TABLE2 CB
INNER JOIN TABLE3 FF
ON FF.SETN_DX = CB.SETN_DX
LEFT OUTER JOIN TABLE5 MP
ON MP.TYX_DX = FF.TYX_DX
WHERE FF.EFF_BFX >= TO_DATE('01-JAN-2013', 'DD-MON-YYYY')) FF
ON MPP.TYX_DX = FF.TYX_DX
Best of luck.
I tried to make your query more readable:
SELECT MPPFF.*
FROM
(SELECT FF.*, MPP.*
FROM
(SELECT MBR.*, MPP.*
FROM
(SELECT MPP.*, MMP.*
FROM
(SELECT MPP.*, RPT.*
FROM TABLE1 MPP
LEFT JOIN (SELECT * FROM TABLE6 RPT, TABLE7 PP WHERE PP.PRTY_DX = RPT.PRTY_DX) RPT ON MPP.AS_DX = RPT.AS_DX) MPP
LEFT JOIN (SELECT * FROM TABLE4) MMP ON MPP.POPL_DX=MMP.POPL_DX) MPP,
(SELECT MBR.* FROM TABLE8 MBR) MBR
WHERE MPP.MEMB_DX = MBR.MEMB_DX) MPP
INNER JOIN (SELECT FF.*, CB.* FROM TABLE2 CB, TABLE3 FF
LEFT JOIN (SELECT * FROM TABLE5 MP ) MP ON MP.TYX_DX = FF.TYX_DX
WHERE FF.SETN_DX = CB.SETN_DX
AND EXTRACT( YEAR FROM FF.EFF_BFX) >=2013) FF ON MPP.TYX_DX = FF.TYX_DX) MPPFF
;
You select 8 different tables and the only WHERE condition is EXTRACT( YEAR FROM FF.EFF_BFX) >= 2013
Unless the tables are tiny it will always take some time to query them all together.
Why do you mix ANSI join syntax and old-style Oracle join syntax?

The multi-part identifier could not be bound - SQL Server 2014

I am trying to solve the error in the below query
Yes I have checked many same questions but still can not figure out the solution
The error:
The multi-part identifier "Table_2.id" could not be bound.
When I remove the inner join the query runs perfectly fine
I have to solve this problem without turning it into explicit joins because i have so many dynamic filtering which add and x=y clauses to the end of the query
Thank you
SELECT TOP 10 username,
NAME,
table_1.authoritylevel,
totalcount,
avglevel,
table_2.pokemonid,
pokemonlevel,
table_2.id,
pokemonexp,
battlecount,
battlevictorycount,
table_1.userid
FROM table_1,
table_2,
table_3,
table_4
LEFT OUTER JOIN (SELECT Count(table_5.offereruserid) AS OfferCount,
table_5.offereduserspokemonsid
FROM table_5
GROUP BY offereduserspokemonsid) innerQuestion
ON innerQuestion.offereduserspokemonsid = table_2.id
WHERE table_3.pokemonid = table_2.pokemonid
AND pokemonplace = 'trade'
AND table_4.pokemonid = table_2.pokemonid
AND table_2.userid = table_1.userid
AND table_2.userid != 1
If you are keen on keeping the implicit joins, you could split your query into several result sets using WITH. According to this article, you can no longer do "implicit outer joins." Give this a try:
WITH OfferCounts as
(
SELECT Count(table_5.offereruserid) AS OfferCount, table_5.offereduserspokemonsid
FROM table_5
GROUP BY offereduserspokemonsid
),
EverythingElse AS
(
SELECT TOP 10 username,
NAME,
table_1.authoritylevel,
totalcount,
avglevel,
table_2.pokemonid,
pokemonlevel,
table_2.id,
pokemonexp,
battlecount,
battlevictorycount,
table_1.userid
FROM table_1,
table_2,
table_3,
table_4,
WHERE table_3.pokemonid = table_2.pokemonid
AND pokemonplace = 'trade'
AND table_4.pokemonid = table_2.pokemonid
AND table_2.userid = table_1.userid
AND table_2.userid != 1
)
Select *
From EverythingElse t1
left join OfferCounts t2 on t1.offereduserspokemonsid = t2.id
The specific problem comes from the use of implicit joins first and then an explicit join. Lesser lines of code is not a very good reason to use implicit joins, specially since it's deprecated.
Another considerations would be to use table aliases, and also to prefix every column with the corresponding table alias, even if the column is unique between those tables for readability and a code that's easier to maintain.
You are also missing the GROUP BY needed for your aggregation function. All in all, the fixed code would be:
SELECT TOP 10 username,
NAME,
T1.authoritylevel,
totalcount,
avglevel,
T2.id,
T2.pokemonid,
pokemonlevel,
pokemonexp,
battlecount,
battlevictorycount,
T1.userid,
Count(T5.offereruserid) AS OfferCount
FROM Table_1 T1
INNER JOIN Table_2 T2
ON T1.userid = T2.userid
INNER JOIN Table_3 T3
ON T2.pokemonid = T3.pokemonid
INNER JOIN Table_4 T4
ON T2.pokemonid = T4.pokemonid
INNER JOIN Table_5 T5
ON T5.offereduserspokemonsid = T2.id
WHERE pokemonplace = 'trade'
AND T2.userid != 1
GROUP BY username,
NAME,
T1.authoritylevel,
totalcount,
avglevel,
T2.id,
T2.pokemonid,
pokemonlevel,
pokemonexp,
battlecount,
battlevictorycount,
T1.userid;
But, as I said, I suggest that you add the corresponding prefixes to those columns.

Postgresql - Having trouble performing left joins on multiple tables

I'm in the process of moving some Mysql queries over to Postgresql and I ran across this one that doesn't work.
select (tons of stuff)
from trip_publication
left join trip_collection AS "tc" on
tc.id = tp.collection_id
left join
trip_author ta1, (dies here)
trip_person tp1,
trip_institution tai1,
trip_location tail1,
trip_rank tr1
ON
tp.id = ta1.publication_id
AND tp1.id = ta1.person_id
AND ta1.order = 1
AND tai1.id = ta1.institution_id
AND tail1.id = tai1.location_id
AND ta1.rank_id = tr1.id
The query seems to be dying on the "trip_author ta1" line, where I marked it above. The actual error message is:
syntax error at or near ","
LINE 77: (trip_author ta1, trip_person tp1, ...
I went through the docs, and it seems to be correct. What exactly am I doing wrong here? Any feedback would be much appreciated.
I don't know postgres, but in regular SQL you would need to a series of LEFT JOIN statements rather than your comma syntax. You seemed to have started this then stopped after the first two.
Something like:
SELECT * FROM
table1
LEFT JOIN table2 ON match1
LEFT JOIN table3 ON match2
WHERE otherFilters
The alternative is the older SQL syntax of:
SELECT cols
FROM table1, table2, table3
WHERE match AND match2 AND otherFilters
There's a couple of other smaller errors in your SQL, like the fact you forgot your tp alias on your first table, and have tried including a where clause (ta1.order = 1) as a joining constraint.
I think this is what you are after:
select (tons of stuff)
from trip_publication tp
left join trip_collection AS "tc" on tc.id = tp.collection_id
left join trip_author ta1 on ta1.publication_id = tp.id
left join trip_person tp1 on tp1.id = ta1.person_id
left join trip_institution tai1 on tai1.id = ta1.institution_id
left join trip_location tail1 on tail1.id = tai1.location_id
left join trip_rank tr1 on tr1.id = ta1.rank_id
where ta1.order = 1
Your left joins are one per table you are joining
left join trip_author ta1 on ....
left join trip_person tp1 on ....
left join trip_institution on ...
...and so on