How to Use Left join in multiple Tables - sql

I need all my records from T3 Table in below query.
how can I use left join statement to solve my problem in oracle.
SELECT COUNT(*)
FROM R
LEFT JOIN RD
ON (R.ID = RD.RES_INFO_ID)
LEFT JOIN RES
ON (R.SEL_EVL_RES_ID = RES.ID)
LEFT JOIN S
ON (S.ID = R.SEL_EVL_ID)
LEFT JOIN D
ON (RD.DEC_DET_ID = D.ID)
LEFT JOIN M
ON (S.EVL_MAS_ID = M.ID)
LEFT JOIN P_RES
ON (P_RES.PRS_ID = RES.PRS_ID)
LEFT JOIN P_MAS
ON (P_MAS.PRS_ID = M.PRS_ID)
LEFT JOIN P_EVL
ON (P_EVL.PRS_ID = S.PRS_ID)
LEFT JOIN P
ON (P.EVL_MAS_ID = M.ID)
LEFT JOIN DM
ON (DM.EVL_RES_INF_DET_ID = RD.ID);
Thanks in advance

If you need all records from T3, then that should be the first table in the FROM clause. All the joins should be LEFT JOINs. I presume you intend:
SELECT COUNT(*)
FROM T3 R LEFT JOIN
T1 S
ON S.ID = R.SELF_EVALUATION_ID LEFT JOIN
T2 RD
ON RD.EVL_RESOURCE_INFO_ID = R.ID LEFT JOIN
T4 RES
ON R.SELF_EVALUATION_RESOURCE_IDRES.ID LEFT JOIN
T5 M
ON S.EVALUATION_MASTER_ID = M.ID LEFT JOIN
T6 D
ON RD.DECENCY_DETAIL_ID = D.ID LEFT JOIN
T7 P
ON P.EVALUATION_MASTER_ID = M.ID LEFT JOIN
T8 DM
ON DM.EVL_RES_INFO_DETAIL_ID = RD.ID;
In the future, follow a simple rule: Never use commas in the FROM clause. Always use explicit JOIN syntax with the join conditions in the ON clause.

Related

BiqQuery Left Outer with an OR condition Error

Ran into the BigQuery limitation that you can't use an OR on a JOIN. Runs fine in Oracle.
Looking for some hints on how to accomplish this in another matter.
The last left outer join produces this error.
LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.
select [col list]
from tablea a
left outer join tableb b on a.id = b.ID
left outer join tabled d on a.id = d.iid
left outer join tablee e on b.id = e.pid and b.cid = e.id
left outer join tablef f on d.runitid = f.id or e.runitid = f.id
Due to additional join dependencies down the stack I switched it to a JOIN which allows the OR condition. More verification of results will be done.

How to make a table left outer join of multiple tables

I am need to join a main table with two feed tables.Table data below:
MainTable
FeedTable
Query I am running is left inner join
Select ID, MT.ColumnA, FT1.ColumnA, FT1.ColumnB, FT2.ColumnA, FT2.ColumnC, FT3.ColumnA, FT3.ColumnD
from MainTable MT
Left Join FeedTable FTI1 on FT1.fk1 = MT.key
Left Join FeedTable FT2 on FT2.fk2 = MT.key
Left Join FeedTable FT3 on FT3.fk3 = MT.key
The output I get is :
The Output I want to get is :
I am assuming left outer join isn't the way to go about this or am I doing the join wrong?
You want the tables in the wrong order. The FeedTable should be first:
Select ft.*, mt1.key as cola, mt2.key as colb, mt3.key colc
from FeedTable ft left join
MainTable mt1
on ft.fk1 = mt1.key left join
MainTable mt2
on ft.fk2 = mt2.key left join
MainTable mt2
on ft.fk3 = mt3.key;

How to replace an OR statement from a join in sql server

I have the following query that uses an or statement on a join, so basically if one condition on the join isn't met it must check the next condition. The problem is that with the OR statement it takes really long to run but when I remove one of the OR conditions it runs instantly. is there a better way to do this with both conditions without using the OR statement so it would speed up the query
select t5.TransactionNumber
,t4.ID
,t3.[Entry] AS Amount
,t2.Address AS AddressDetail
,t1.PhoneNumber AS ContactNumber
FROM Table1 t1 (NOLOCK)
JOIN Table2 t2 (NOLOCK) ON t2.FicaID = t1.FicaId
inner join Table3 t3 (NOLOCK) ON (t3.ID = t2.ID AND t3.Code = t2.Code) or (t3.TypeID = t2.TypeID) //on this join i have an or statement if one condition isnt met it must check the next condition
LEFT JOIN Table4 t4 (NOLOCK) ON t4.Result = t3.Result
LEFT JOIN Table5 t5 (NOLOCK) ON t5.AccNum = t3.AccNum
where t1.date>'2018-09-01' and t1.date<'2018-09-30'
By the rule of distributivity in logic,
P OR (Q AND R) can be written as
(P OR Q) AND (P OR R).. maybe that helps?
You could try by using left join and COALESCE function
select t5.TransactionNumber
,t4.ID
,COALESCE(t3.[Entry],t33.[Entry]) AS Amount
,t2.Address AS AddressDetail
,t1.PhoneNumber AS ContactNumber
FROM Table1 t1 (NOLOCK)
JOIN Table2 t2 (NOLOCK) ON t2.FicaID = t1.FicaId
left join Table3 t3 (NOLOCK) ON (t3.ID = t2.ID AND t3.Code = t2.Code)
left join Table3 t33 (t33.TypeID = t2.TypeID) //I moved it to left join
LEFT JOIN Table4 t4 (NOLOCK) ON t4.Result = t3.Result
LEFT JOIN Table5 t5 (NOLOCK) ON t5.AccNum = t3.AccNum
where t1.date>'2018-09-01' and t1.date<'2018-09-30'
You can try below query :
select * from
(
select t5.TransactionNumber
,t4.ID
,t3.[Entry] AS Amount
,t2.Address AS AddressDetail
,t1.PhoneNumber AS ContactNumber
FROM Table1 t1 (NOLOCK)
JOIN Table2 t2 (NOLOCK) ON t2.FicaID = t1.FicaId
inner join Table3 t3 (NOLOCK) ON (t3.ID = t2.ID AND t3.Code = t2.Code)
)A
join Table3 t3 (NOLOCK) ON (A.TypeID = t3.TypeID)
LEFT JOIN Table4 t4 (NOLOCK) ON t4.Result = t3.Result
LEFT JOIN Table5 t5 (NOLOCK) ON t5.AccNum = t3.AccNum
where t1.date>'2018-09-01' and t1.date<'2018-09-30'

Adding more joins to a select

I am having some trouble trying to add 2 more joins to a select. The bellow works for me:
FROM
TABLE1 A
INNER JOIN TABLE2 B ON A.ID = B.ID
LEFT JOIN TABLE3 C ON A.REQUESTED_BY = C.USER_NAME
LEFT JOIN TABLE3 D ON A.COORDINATOR = D.USER_NAME
INNER JOIN TABLE4 E ON A.ID = E.PARENT_ID
INNER JOIN TABLE5 F ON E.ID = F.ID
But I need to get more information, so I tried something like this (added the last 2 rows):
FROM
TABLE1 A
INNER JOIN TABLE2 B ON A.ID = B.ID
LEFT JOIN TABLE3 C ON A.REQUESTED_BY = C.USER_NAME
LEFT JOIN TABLE3 D ON A.COORDINATOR = D.USER_NAME
INNER JOIN TABLE4 E ON A.ID = E.PARENT_ID
INNER JOIN TABLE5 F ON E.ID = F.ID
INNER JOIN TABLE6 G ON A.ID = B.ID
LEFT JOIN TABLE3 H ON G.COORDINATOR = H.USER_NAME
And this isn't working like it should.
Question: How can I add the last two joins to make the select works? Thanks.
You're not actually joining to TABLE6 (G) anywhere. I would think that this join:
INNER JOIN TABLE6 G ON A.ID = B.ID
should be something like this instead:
INNER JOIN TABLE6 G ON A.ID = G.ID
And as a side note, I hope you're using table aliases that are more meaningful than A, B, C, etc. in your real code. ;-)

SQL Server - use columns from the main query in the subquery

Is there any way to get a column in real time, from a main query, and use it in a subquery?
Something like this: (Use A.item in the subquery)
SELECT item1, *
FROM TableA A
INNER JOIN
(
select *
from TableB B
where A.item = B.item
) on A.x = B.x;
Ok, here is the real thing:
I need to modify this existing query. It worked before, but now that the database changed, I need to do some modifications, add some comparisons. As you can see there are a lot of JOINS, and one of them is a subquery. I need to add a comparison from a column from the main query (from the table T0 for example) to the subquery (like this: T6.UnionAll_Empresa = T0.UnionALl_Empresa)
Select T0.UnionAll_Empresa,<STUFF>
from [UNION_ALL_BASES]..OINV T0 with (nolock)
inner join [UNION_ALL_BASES]..INV6 T1 with (nolock) on t0.DocEntry = t1.DocEntry and t0.UnionAll_Empresa = t1.UnionAll_Empresa
inner join
(
select
t1.CompanyID,
T2.CompanyDb,
t1.OurNumber,
T6.BankCode,
T6.BankName,
T3.[Description] Situation,
T1.[Status],
T5.Descrption nomeStatus,
T1.Origin,
T1.DocEntry,
T1.DocType,
T1.ControlKey,
T1.CardCode,
T4.[Description] ContractBank,
T1.PayMethodCode,
T1.DueDate,
T1.DocDate,
T1.InstallmentID,
T1.InstallmentValue,
T1.Correction,
T1.InterestContractural,
T1.FineContract,
T1.ValueAbatment,
T1.ValueDiscount,
T1.ValueFineLate,
T1.ValueInterestDaysOfLate,
T1.OtherIncreases,
T1.ValueInWords,
T1.ValueDocument,
T1.DigitalLine,
T1.Document
from [IntegrationBank]..BillOfExchange T1 with (nolock)
inner join [InterCompany2]..CompanyHierarchy T2 with (nolock) on T1.CompanyID = T2.ID
left join [IntegrationBank]..BillOfExchangeSituation T3 with (nolock) on T1.Situation = T3.ID
inner join [IntegrationBank]..ContractBank T4 with (nolock) on T1.ContractBank = T4.ID
inner join [IntegrationBank]..BoeStatus T5 with (nolock) on T1.[Status] = T5.ID
inner join [UNION_ALL_BASES]..ODSC T6 with (nolock) on T4.BankKey = T6.AbsEntry and **T6.UnionAll_Empresa = T0.UnionALl_Empresa** --I need to do this
where T1.[Status] <> 5
and T2.CompanyDb = **T0.UnionAll_Empresa** --I need to do this
) TBI on (T1.DocEntry = TBI.DocEntry and T1.InstlmntID = TBI.InstallmentID and TBI.DocType = T1.ObjType )
inner join [UNION_ALL_BASES]..OCTG T2 on T0.GroupNum = T2.GroupNum and T0.UnionAll_Empresa = T2.UnionAll_Empresa
inner join [UNION_ALL_BASES]..OSLP T3 on T0.SlpCode = T3.SlpCode and T0.UnionAll_Empresa = T3.UnionAll_Empresa
where not exists (select 1
from [UNION_ALL_BASES]..RIN1 A with (nolock)
inner join [UNION_ALL_BASES]..ORIN B with (nolock) on A.DocEntry = B.DocEntry and A.UnionAll_Empresa = B.UnionAll_Empresa
where A.BaseEntry = T0.DocEntry
and B.SeqCode = ''1'' )
You can user OUTER APPLY
SELECT *
FROM tbl1
OUTER APPLY ( SELECT TOP 1
currency_id,
SUM(taxrate) AS taxrate
FROM tbl2
WHERE wuptr.currency_id = tbl1.currency_id
GROUP BY tbl2.currencyid
)
You don't need a subquery for that:
SELECT item1, *
FROM TableA A
INNER JOIN
TableB B
ON A.item = B.item
AND A.x = B.x;
I can't think of a scenario where you would need to JOIN on a subquery with a filter like that where it wouldn't be equivalent to just reference the field directly in the outer query.
You can reference the outer table in the subquery in the WHERE clause, though:
SELECT <stuff>
FROM Table t
WHERE EXISTS (SELECT 1 from TableB B
WHERE t.id = b.id)
EDIT
For your actual code, just change the JOIN criteria to this:
) TBI on (T1.DocEntry = TBI.DocEntry
and T1.InstlmntID = TBI.InstallmentID
and TBI.DocType = T1.ObjType
AND TBI.CompanyDB = T0.UnionAll_Empresa )
If you want to join on to a subquery and "get a column in real-time"/ reference a column from the main query, then there is a trick to doing this.
You can't access the tables which are outside of the subquery if it's used as an aliased table, in other words, this SQL can never access A:
...
INNER JOIN
(
select *
from TableB B
where A.item = B.item
) on A.x = B.x;
The way to access A would be like this:
SELECT item1, *
FROM TableA A
INNER JOIN TableB on TableB.item = TableA.item and TableB.item in
(
select top 1 B.Item
from TableB B
where A.item = B.item
)
Just ignore the "top 1" piece, I just added that to show that there may a reason for doing a join like this.
So, basically if you want to reference an item from the query in the subquery, just move the subquery to the ON section of a join and use the IN keyword as illustrated above.
You can do this by naming the tables of the main query and the nested query.
For example:
SELECT continent, name, population FROM world x
WHERE population >= ALL
(SELECT population FROM world y
WHERE y.continent=x.continent
AND population>0)
reference: http://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial
Not sure why people are over-complicating this. #JNK is correct that you can move the predicate into the main query. For completeness, I will demonstrate.
You have two predicates in your subquery that reference T0:
T6.UnionAll_Empresa = T0.UnionAll_Empresa
T2.CompanyDb = T0.UnionAll_Empresa
The first is an INNER JOIN predicate on the table T6, and the second a WHERE clause - these are both "hard" filters, and will filter out results that don't match (unlike a LEFT OUTER JOIN which will simply set reference to that table's values to NULL).
Well, since T6.UnionAll_Empresa and T2.CompanyDb both need to filter against T0.UnionAll_Empresa, then we can simply change the INNER JOIN predicate on T6 to this:
T2.CompanyDb = T6.UnionAll_Empresa
Then, we can remove the WHERE clause in the subquery, and we can add this JOIN predicate to TBI in the main query:
TBI.CompanyDb = T0.UnionAll_Empresa
...making the entire query this:
Select T0.UnionAll_Empresa,<STUFF>
from [UNION_ALL_BASES]..OINV T0 with (nolock)
inner join [UNION_ALL_BASES]..INV6 T1 with (nolock) on t0.DocEntry = t1.DocEntry and t0.UnionAll_Empresa = t1.UnionAll_Empresa
inner join
(
select
t1.CompanyID,
T2.CompanyDb,
t1.OurNumber,
T6.BankCode,
T6.BankName,
T3.[Description] Situation,
T1.[Status],
T5.Descrption nomeStatus,
T1.Origin,
T1.DocEntry,
T1.DocType,
T1.ControlKey,
T1.CardCode,
T4.[Description] ContractBank,
T1.PayMethodCode,
T1.DueDate,
T1.DocDate,
T1.InstallmentID,
T1.InstallmentValue,
T1.Correction,
T1.InterestContractural,
T1.FineContract,
T1.ValueAbatment,
T1.ValueDiscount,
T1.ValueFineLate,
T1.ValueInterestDaysOfLate,
T1.OtherIncreases,
T1.ValueInWords,
T1.ValueDocument,
T1.DigitalLine,
T1.Document
from [IntegrationBank]..BillOfExchange T1 with (nolock)
inner join [InterCompany2]..CompanyHierarchy T2 with (nolock) on T1.CompanyID = T2.ID
left join [IntegrationBank]..BillOfExchangeSituation T3 with (nolock) on T1.Situation = T3.ID
inner join [IntegrationBank]..ContractBank T4 with (nolock) on T1.ContractBank = T4.ID
inner join [IntegrationBank]..BoeStatus T5 with (nolock) on T1.[Status] = T5.ID
inner join [UNION_ALL_BASES]..ODSC T6 with (nolock) on T4.BankKey = T6.AbsEntry and T2.CompanyDb = T6.UnionAll_Empresa
where T1.[Status] <> 5
) TBI on (T1.DocEntry = TBI.DocEntry and T1.InstlmntID = TBI.InstallmentID and TBI.DocType = T1.ObjType and TBI.CompanyDb = T0.UnionAll_Empresa)
inner join [UNION_ALL_BASES]..OCTG T2 on T0.GroupNum = T2.GroupNum and T0.UnionAll_Empresa = T2.UnionAll_Empresa
inner join [UNION_ALL_BASES]..OSLP T3 on T0.SlpCode = T3.SlpCode and T0.UnionAll_Empresa = T3.UnionAll_Empresa
where not exists (
select 1
from [UNION_ALL_BASES]..RIN1 A with (nolock)
inner join [UNION_ALL_BASES]..ORIN B with (nolock) on A.DocEntry = B.DocEntry and A.UnionAll_Empresa = B.UnionAll_Empresa
where A.BaseEntry = T0.DocEntry
and B.SeqCode = ''1''
)
This is entirely equivalent to what you have, and removes any reference to T0 from your subquery.
You can also use WITH
http://msdn.microsoft.com/en-us/library/ms175972.aspx