Clarification on PL/SQL JOINS in this Query - sql

I have a Query returning 377 Rows
Select Cm.Customerid,Cm.Customername,Ad.Addressid,Ad.Addressline1,
Stm.Statename,Ctm.Cityname,Dm.Districtname
From Crm.Customers Cm
inner join Crm.Customeraddress Ad on Ad.Customerid=Cm.Customerid
Inner Join Ehis.Statemaster Stm On Stm.Stateid=Ad.Stateid
Inner Join Ehis.Citymaster Ctm On Ctm.Cityid=Ad.Cityid
inner join Ehis.Districtmaster dm on Dm.Districtid=Ad.Districtid
But if i add one more join to this (i.e)
Select
Cm.Customerid,Cm.Customername,Ad.Addressid,Ad.Addressline1,
Stm.Statename,Ctm.Cityname,Dm.Districtname
From Crm.Customers Cm
inner join Crm.Customeraddress Ad on Ad.Customerid=Cm.Customerid
inner join crm.agreements ag on ag.customerid=cm.customerid
Inner Join Ehis.Statemaster Stm On Stm.Stateid=Ad.Stateid
Inner Join Ehis.Citymaster Ctm On Ctm.Cityid=Ad.Cityid
inner join Ehis.Districtmaster dm on Dm.Districtid=Ad.Districtid
My query is not returning any rows. Is there any Problem in using inner join for statemasters,city n district masters. Pls clarify the same.

The problem doesn't appear to be with statemaster, citymaster or districtmaster, as these are in your original query that returns data.
The additional line (below) looks to be the culprit.
inner join crm.agreements ag on ag.customerid=cm.customerid
Presumably there are no records on the agreements table with a matching customerid on the customers table.
To prove that is the case, you could change that line to
left join crm.agreements ag on ag.customerid=cm.customerid
If you get your 377 records back, then you'll need to check the data in agreements.

Related

TSQL: How does this JOIN resolve?

I am doing these joins:
from #lps_at_lines2 as l2
left join jobmatl as jm on l2.item = jm.item
inner join job as j on jm.job = j.job
and jm.suffix = j.suffix
I'm not sure how the join would resolve and the official documentation is like reading hieroglyphics to me.
My guess is that first #lps_at_lines2 gets LEFT JOIN'd to jobmatl and then somehow job gets INNER JOIN'd to jm afterwards. Is that correct?
In a FROM clause, JOINs are parsed left to right -- the reading order in English. So, the LEFT JOIN is processed (logically) before the INNER JOIN.
The INNER JOIN conditions include:
jm.job = j.job and jm.suffix = j.suffix
These refer to the second table of the LEFT JOIN. Because NULL values fail, the INNER JOIN is turning the preceding LEFT JOIN into an INNER JOIN. In other words, you should get the same results using INNER JOIN for both.
Note that you can adjust the prioritization by using parentheses, but your version of the query does not do this.
In general, when mixing inner joins and left joins, I start by including all the inner joins and then LEFT JOINing the additional tables.

Duplicate results due to multiple left outer joins

My query is as below
select DISTINCT
wftransaction.PERSONID,
pr.PRNUM,
pr.DESCRIPTION,
pr.PR1,
prline.GLDEBITACCT,
wftransaction.TRANSDATE,
prstatus.CHANGEBY
prstatus.CHANGEDATE,
prstatus.STATUS,
prstatus.MEMO
from pr
left outer join wftransaction pr.PRID = wftransaction.ORNERID and wftransaction.OWNERTABLE ='PR'
left outer join prline on pr.PRNUM = prline.PRNUM
left outer join prstatus on pr.PRNUM= prstatus.PRNUM
The result given by my query has duplicate results.Please do help me eliminate the redundant/repeating outputs.
When I put distinct this is what happens, https://i.stack.imgur.com/I2jnN.jpg,
I should only see 2 outputs with the same "STATUS" i.e.(COMPOSING) or (APPR) since they have different "GLDEBITACCT", other than that, there should be no more duplicates.
This is the picture of my Code and Result Set
i think you should be using inner join because if left join where being used all data from table A will repeatedly shows as the table B has its foreign key, or might sometimes you are lacking of WHERE clauses it depends on your query, it will be more helpful to others if you can paste the whole query and their structures with expected results.
https://www.codeproject.com/kb/database/visual_sql_joins.aspx
Good idea will be to place a simple DISTINCT clause in the query
select DISTINCT
wftransaction.PERSONID,
pr.PRNUM,
pr.DESCRIPTION,
pr.PR1,
prline.GLDEBITACCT,
wftransaction.TRANSDATE,
prstatus.CHANGEBY
prstatus.CHANGEDATE,
prstatus.STATUS,
prstatus.MEMO
from pr
left outer join wftransaction pr.PRID = wftransaction.ORNERID and wftransaction.OWNERTABLE ='PR'
left outer join prline on pr.PRNUM = prline.PRNUM
left outer join prstatus on pr.PRNUM= prstatus.PRNUM

returned no of rows different on left join

i have two sql query in one of them i perform left outer join, both should return same no of records but returned no of rows are different in both the sql queries
select Txn.txnRecNo
from Txn
inner join Person on Txn.uwId = Person.personId
full outer join TxnInsured on Txn.txnRecNo = TxnInsured.txnRecNo
left join TxnAdditionalInsured on Txn.txnRecNo = TxnAdditionalInsured.txnRecNo
where Txn.visibleFlag=1
and Txn.workingCopy=1
returned 20 records
select Txn.txnRecNo
from Txn
inner join Person on Txn.uwId = Person.personId
full outer join TxnInsured on Txn.txnRecNo = TxnInsured.txnRecNo
where Txn.visibleFlag=1
and Txn.workingCopy=1
returned 15 records
I suspect that the TxnAdditionalInsured table have duplicate records. use distinct
select distinct Txn.txnRecNo
from Txn
inner join Person on Txn.uwId = Person.personId
full outer join TxnInsured on Txn.txnRecNo = TxnInsured.txnRecNo
left join TxnAdditionalInsured on Txn.txnRecNo = TxnAdditionalInsured.txnRecNo
where Txn.visibleFlag=1
and Txn.workingCopy=1
A left join will produce all rows from the left side of the join at least once in the result set.
But if your join conditions are such that there are multiple rows from the right side that match a particular row on the left, that left row will appear multiple times in the result (as many times as it is matched with a right row).
So, if the results are unexpected, your join criteria aren't are strict as they need to be or you do not understand your data as well as you thought you did.
Unlike the other answers, I would not suggest just adding distinct - I'd suggest you investigate your data and determine whether your ON clause needs strengthening or if your data is in fact incorrect. Adding distinct to "make the results look right" is usually a poor decision - prefer to investigate and get the correct query written.
Try this:
select distinct Txn.txnRecNo --> added distinct here
from Txn
inner join Person on Txn.uwId = Person.personId
full outer join TxnInsured on Txn.txnRecNo = TxnInsured.txnRecNo
left join TxnAdditionalInsured on Txn.txnRecNo = TxnAdditionalInsured.txnRecNo
where Txn.visibleFlag=1
and Txn.workingCopy=1

Query to Sum Numbers Based on Location (State)

I'm trying to write a query that will summarize all of the procedures performed during the calendar year 2013, whether the event happened on a mobile drive or at a fixed site within a particular state.
Every Drive is Unique and will either occur at a Fixed Site (CenterID) or on a Mobile Site, which are associated with Accounts (AccountID). My query looks like this:
select sum(proceduresperformed), sum(productscollected)
from DriveProjectionAndCollectedTotals DPaCT
inner join rpt_DriveMaster DM on DPaCT.DriveID=DM.DriveID
left outer join rpt_Accounts Acct on DM.AccountID=Acct.AccountID
left outer join rpt_CenterDetail CD on DM.CenterID=CD.CenterID
inner join rpt_AddressDetail AD on Acct.AccountID=AD.AccountID
inner join rpt_AddressDetail AD2 on CD.CenterID=AD2.CenterID
where AD.State='FL'
or AD2.State='FL'
and Year(DM.FromDateTime)=2013
But these numbers are really high and incorrect. So what I did was remove one of the joins (either the Account or the CenterDetail) and run the query twice to get numbers that look much more in line with what is expected:
select sum(proceduresperformed), sum(productscollected)
from DriveProjectionAndCollectedTotals DPaCT
inner join rpt_DriveMaster DM on DPaCT.DriveID=DM.DriveID
left outer join rpt_Accounts Acct on DM.AccountID=Acct.AccountID
--left outer join rpt_CenterDetail CD on DM.CenterID=CD.CenterID
inner join rpt_AddressDetail AD on Acct.AccountID=AD.AccountID
--inner join rpt_AddressDetail AD2 on CD.CenterID=AD2.CenterID
where AD.State='FL'
--or AD2.State='FL'
and Year(DM.FromDateTime)=2013
How can I fix the original query to summarize the two columns in a way that does not basically triple the expected value?
The original query returns:
And running the query with Accounts and Centers separately:
I went back and used a UNION statement to give me the correct answer:
select sum(procperf) as 'Procedures Performed'
from (
select sum(proceduresperformed) as procperf
from DriveProjectionAndCollectedTotals DPaCT
inner join rpt_DriveMaster DM on DPaCT.DriveID=DM.DriveID
left outer join rpt_Accounts Acct on DM.AccountID=Acct.AccountID
inner join rpt_AddressDetail AD on Acct.AccountID=AD.AccountID
where AD.State='FL'
and Year(DM.FromDateTime)=2013
UNION
select sum(proceduresperformed) as procperf
from DriveProjectionAndCollectedTotals DPaCT
inner join rpt_DriveMaster DM on DPaCT.DriveID=DM.DriveID
left outer join rpt_CenterDetail CD on DM.CenterID=CD.CenterID
inner join rpt_AddressDetail AD2 on CD.CenterID=AD2.CenterID
where AD2.State='FL'
and Year(DM.FromDateTime)=2013
) as a;

SQL Cascading Join

I have the following join as part of a View:
from studies
inner join orders on orders.orderId = studies.orderId
left outer join referrers on referrers.referrerId = orders.referrerId
left outer join professionalDegrees referrerDegree on referrerDegree.professionalDegreeId = referrers.professionalDegreeId
referrers.professionalDegreeId column is NOT NULL. In queries that are limited to the referrers scope, the JOIN to professionalDegrees is INNER.
In the View above, if I INNER JOIN on professionalDegrees, there are no rows returned where orders.referrerId is NULL. When I LEFT JOIN on professionalDegrees the row is returned with NULL referrerId, as desired.
Does INNER vs LEFT matter to performance in this case? Is there a better way to write this JOIN?