Full outer join a table to another table that's being left joined to the main table - sql

So i've got hte below code that works for the most part but when I'm trying to bring in the last table i cant get the expected results.
SELECT
CASE
WHEN CCO.Account_Manager__c IS NULL THEN Opp.OwnerId ELSE CCO.Account_Manager__c
END AS AccountManager,
CCO.Account_Associate__c as ClientOfficeAccountAssociate,
Opp.OwnerId as AccountOwnerId,
CCO.Account_Manager__c as ClientOfficeAM,
ACC.Name as AccountName,
OPP.Forum_Monthly_Recurring_Revenue_MRR__c,
PAYG.Revenue
LEFT JOIN `round-cacao-234512.salesforce.Opportunity` as OPP
ON OPP.Id = Split.OpportunityId AND OPP.OwnerId = Split.SplitOwnerId
LEFT JOIN `round-cacao-234512.salesforce.Account` as ACC
on ACC.Id = OPP.AccountId
LEFT JOIN `round-cacao-234512.salesforce.User` as USER
ON USER.Id = OPP.OwnerId
LEFT JOIN `round-cacao-234512.salesforce_df.Company_Client_Office__c` as CCO
ON CCO.Opportunity__c = OPP.Id
LEFT JOIN `round-cacao-234512.salesforce.Client_Office_Intranet__c` as COI
ON COI.Id = CCO.Client_Office_Intranet__c
LEFT JOIN `round-cacao-234512.salesforce.RecordType` as RT
ON RT.Id = OPP.RecordTypeId
LEFT JOIN `commercial-analysis.materialised.2022AMDashForumRRQuotas` as Quota
on Quota.AccountID = CCO.Account_Manager__c OR Quota.AccountID = Opp.OwnerId
LEFT JOIN `commercial-analysis.2022_AM_Territory.FPAYG_Quotas` as PAYGQuota
on PAYGQuota.ClientOffice = COI.Name
Full Outer JOIN `round-cacao-234512.materialised.2022AMDashPAYGRevenue` PAYGRev
on PAYGRev.ClientOffice = COI.Name
So my last table round-cacao-234512.materialised.2022AMDashPAYGRevenue will be joined on clientoffice but will also have client offices that don't appear in COI, so I want those to come in with nulls on all the values that don't match up.
Hope that makes sense

Related

Big Query : LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join

I am writing an equivalent logic in BQ as in my source system. In source SQL server side it is working fine. But in Big query it is failing with the OR condition in the last left outer join condition. If I am moving the OR condition in the where clause it is giving wrong count. Need help to fix this issue. How can I re write the below query ?
SELECT count(*)
FROM stprof PRO
INNER JOIN stdim DIM
ON (DIM.diSet = PRO.diSet)
INNER JOIN DQConfig CFG
ON (CFG.ConSet = PRO.ConSet)
LEFT OUTER JOIN AgSt CCT
ON (CCT.StSet = PRO.StSet)
INNER JOIN stprof SummPRO
ON (SummPRO.diSet = DIM.SummdiSet AND
SummPRO.dIntervalStart = PRO.dIntervalStart AND
SummPRO.SiteId = PRO.SiteId AND
SummPRO.nDuration = PRO.nDuration)
LEFT OUTER JOIN AgSt SummCCT
ON (SummCCT.StSet = SummPRO.StSet)
LEFT OUTER JOIN AgentStatus SummSTS
ON (
SummSTS.StSet = SummPRO.StSet
OR
SummSTS.StSet = PRO.StSet)
WHERE DIM.cType = 'A'
You can replace LEFT JOIN with CROSS JOIN and move condition from ON clause to WHERE clause as in below example
#standardSQL
SELECT COUNT(*)
FROM stprof PRO
INNER JOIN stdim DIM
ON DIM.diSet = PRO.diSet
INNER JOIN DQConfig CFG
ON CFG.ConSet = PRO.ConSet
LEFT OUTER JOIN AgSt CCT
ON CCT.StSet = PRO.StSet
INNER JOIN stprof SummPRO
ON SummPRO.diSet = DIM.SummdiSet
AND SummPRO.dIntervalStart = PRO.dIntervalStart
AND SummPRO.SiteId = PRO.SiteId
AND SummPRO.nDuration = PRO.nDuration
LEFT OUTER JOIN AgSt SummCCT
ON SummCCT.StSet = SummPRO.StSet
CROSS JOIN AgentStatus SummSTS
WHERE DIM.cType = 'A'
AND (
SummSTS.StSet = SummPRO.StSet
OR SummSTS.StSet = PRO.StSet
)

summation in sql

I have a query result tabletable of result i would like to sum the bill amount such that it returns one row with a distinct account ,balance,sum billed amount fPreviousReading,
fCurrentReading,
fConsumption .
result should be
1.account 11074
2.balance269.49
3.sumbilledamount 520.48
4. fPreviousReading 574
5 fCurrentReading 612
6 fConsumption 38
Thanks
query
select
Ten.Account,
ten.DCBalance AS Balance,
SUM(T.fInclusiveAmount)AS BilledAmount,
MRD.fPreviousReading,
MRD.fCurrentReading ,
MRD.fConsumption ,
T.cDescription
from _mtblTransactions T
left join _mtblProperties P ON P.idProperty = T.iPropertyID
left join _mtblPropertyPortions PP ON PP.idPropertyPortions = T.iPortionID
left join _mtblPropertyPortionServices PPS ON PPS.idPropertyPortionServices = T.iPropertyPortionServiceID
left join _mtblCategories Cat ON Cat.idCategory = PP.iPortionUsageID
left join _mtblServices S ON PPS.iPortionServiceID = S.idService
left join _mtblServiceGroups SG ON S.iServiceGroupID = SG.idServiceGroup
left join _mtblRateTariffs RT ON RT.idRateTariffs = PPS.iServiceRateTariffID
left join Client Ten ON T.iCustomerID = Ten.DCLink
left join _mtblMeters M ON PPS.iPropertyPortionMeterID = M.idMeter
left join _mtblWalkDetails WD ON WD.iWalkMeterID = PPS.iPropertyPortionMeterID
left join _mtblWalks W ON WD.iWalkID = W.idWalk
left join Client Own ON P.iPropertyOwnerID = Own.DCLink
left outer join _mtblRegions R on R.idRegions = P.iPropertyRegionID
left outer join _mtblSubRegions SR on SR.idSubRegions = P.iPropertySubRegionID
left outer join _mtblAreas A on A.idAreas = P.iPropertyAreaID
left join _etblPeriod PER ON T.iPeriodID = PER.idPeriod
left join _mtblMeterReadingDetails MRD ON T.iMeterID = MRD.iMeterReadingsMeterID and T.iPeriodID = MRD.iBillingPeriodID
and MRD.iReadingType=0
Where
oWN.Account='11074'
and idPeriod='79'
GROUP BY Ten.Account,ten.DCBalance,MRD.fPreviousReading, MRD.fCurrentReading, MRD.fConsumption, T.cDescription
As I don't know your data, there is a possibility I wrote you a code that would return some double rows. But that is a problem you can easily handle.
Try it, nevertheless:
SELECT t1.Account,
t1.Balance,
t1.BilledAmount,
t1.fPreviousReading,
t1.fCurrentReading,
t1.fConsumption,
t2.cDescription
FROM (SELECT Ten.Account,
ten.DCBalance AS Balance,
SUM (T.fInclusiveAmount) AS BilledAmount,
SUM (MRD.fPreviousReading) AS fPreviousReading,
SUM (MRD.fCurrentReading) AS fCurrentReading,
SUM (MRD.fConsumption) AS fConsumption
FROM _mtblTransactions T
left join _mtblProperties P ON P.idProperty = T.iPropertyID
left join Client Ten ON T.iCustomerID = Ten.DCLink
left join Client Own ON P.iPropertyOwnerID = Own.DCLink AND oWN.Account='11074'
left join _etblPeriod PER ON T.iPeriodID = PER.idPeriod
left join _mtblMeterReadingDetails MRD ON T.iMeterID = MRD.iMeterReadingsMeterID and T.iPeriodID = MRD.iBillingPeriodID
and MRD.iReadingType=0
and idPeriod='79'
GROUP BY Ten.Account,ten.DCBalance) t1
JOIN (SELECT T.cDescription,
Ten.Account,
ten.DCBalance
FROM _mtblTransactions T
left join Client Ten ON T.iCustomerID = Ten.DCLink) t2 ON t2.Account = t1.Account AND t2.DCBalance = t1.DCBalance

Left Join not working

I am a SQL Server beginner and so I have been using MS Access to create queries and then have been amending them for SQL Server.
I have created a query which includes a left join, which works perfectly in Access but when I copy the SQL code across to SQL Server it does not show the null values and I cannot work out why.
I want to show all of the attribute values whether they include a value or not. Can anyone help? The code is as follows:
SELECT DISTINCT
tbLease.LeaseTitle
, tbAttributeValue.AttributeTemplateDefinitionLinkID
, tbAttributeValue.Value
FROM
((((tbBusinessUnit
LEFT JOIN
tbAttributeValue ON tbBusinessUnit.BusinessUnitID = tbAttributeValue.ParentID)
INNER JOIN
tbBuildingLinkBusinessUnit ON tbBusinessUnit.BusinessUnitID = tbBuildingLinkBusinessUnit.BusinessUnitID)
INNER JOIN
tbBuilding ON tbBuildingLinkBusinessUnit.BuildingID = tbBuilding.BuildingID)
INNER JOIN
(tbUnitLocation
INNER JOIN
tbUnit ON tbUnitLocation.UnitID = tbUnit.UnitID)
ON tbBuilding.BuildingID = tbUnitLocation.LocationID)
INNER JOIN
tbLease ON tbUnit.UnitID = tbLease.UnitID
WHERE
(((tbAttributeValue.AttributeTemplateDefinitionLinkID) = 30
Or (tbAttributeValue.AttributeTemplateDefinitionLinkID) = 31
Or (tbAttributeValue.AttributeTemplateDefinitionLinkID) = 32));
Hard to say what you want without some examples but you might want this:
WHERE coalesce(tbAttributeValue.AttributeTemplateDefinitionLinkID,30) in (30,31,32);
This will give you items where AttributeTemplateDefinitionLinkID is null
(that is it did not join on the left join) OR is one of those 3 values.
Right now if you don't join with the left join it will not display that row because of the where condition, so your left join is the same as an inner join.
The NULL values you would normally see with a left join are getting filtered out by your WHERE clause.
Any time you add filters to a WHERE clause that apply to an outer joined table, it will effectively make it the same as an inner join unless you include NULL values as an option in your where clause as well.
SELECT DISTINCT
tbLease.LeaseTitle,
tbAttributeValue.AttributeTemplateDefinitionLinkID,
tbAttributeValue.Value
FROM
tbBusinessUnit
LEFT JOIN tbAttributeValue ON tbBusinessUnit.BusinessUnitID = tbAttributeValue.ParentID
INNER JOIN tbBuildingLinkBusinessUnit ON tbBusinessUnit.BusinessUnitID = tbBuildingLinkBusinessUnit.BusinessUnitID
INNER JOIN tbBuilding ON tbBuildingLinkBusinessUnit.BuildingID = tbBuilding.BuildingID
INNER JOIN tbUnitLocation ON tbBuilding.BuildingID = tbUnitLocation.LocationID
INNER JOIN tbUnit ON tbUnitLocation.UnitID = tbUnit.UnitID
INNER JOIN tbLease ON tbUnit.UnitID = tbLease.UnitID
WHERE
tbAttributeValue.AttributeTemplateDefinitionLinkID in (30, 31, 32)
or tbAttributeValue.AttributeTemplateDefinitionLinkID is null
Move the right table filters from where clause to ON condition when you are using Left Outer Join else Left join will be implicitly converted to INNER JOIN. Try this
SELECT DISTINCT tblease.leasetitle,
tbattributevalue.attributetemplatedefinitionlinkid,
tbattributevalue.value
FROM tbbusinessunit
LEFT JOIN tbattributevalue
ON tbbusinessunit.businessunitid = tbattributevalue.parentid
AND ( tbattributevalue.attributetemplatedefinitionlinkid IN
( 30, 31, 32 )
OR tbattributevalue.attributetemplatedefinitionlinkid IS
NULL )
INNER JOIN tbbuildinglinkbusinessunit
ON tbbusinessunit.businessunitid =
tbbuildinglinkbusinessunit.businessunitid
INNER JOIN tbbuilding
ON tbbuildinglinkbusinessunit.buildingid = tbbuilding.buildingid
INNER JOIN tbunitlocation
ON tbbuilding.buildingid = tbunitlocation.locationid
INNER JOIN tbunit
ON tbunitlocation.unitid = tbunit.unitid
INNER JOIN tblease
ON tbunit.unitid = tblease.unitid

SQL JOIN STRUGGLE

SELECT Count(TRK.REACTIE_ID),
S.UITGEVER,
S.NAAM,
S.BESCHRIJVING,
S.AFBEELDING_BESTANDSPAD,
S.SUBTITLE,
C.NAAM
FROM CATEGORIEEN_KOPPELTABEL CK
LEFT OUTER JOIN CATEGORIE C
ON C.CATEGORIE_ID = CK.CATEGORIE_ID
LEFT OUTER JOIN TV_SHOW S
ON S.TV_SHOW_ID = CK.TV_SHOW_ID
AND S.NAAM = 'South Park'
FULL OUTER JOIN TVSHOW_REACTIES_KOPPELTABEL TRK
ON TRK.TV_SHOW_ID = S.TV_SHOW_ID
GROUP BY TRK.TV_SHOW_ID,
S.UITGEVER,
S.NAAM,
S.BESCHRIJVING,
S.AFBEELDING_BESTANDSPAD,
S.SUBTITLE,
C.NAAM;
I can't figure out why I can't get only the first row back.
Now I get three rows back with null values and I want only to get the first row. Please help!
rows without nulls use the following FROM statement and keep the rest of query the same.:
FROM CATEGORIEEN_KOPPELTABEL CK
JOIN CATEGORIE C ON C.CATEGORIE_ID = CK.CATEGORIE_ID
JOIN TV_SHOW S ON S.TV_SHOW_ID = CK.TV_SHOW_ID AND S.NAAM = 'South Park'
JOIN TVSHOW_REACTIES_KOPPELTABEL TRK ON TRK.TV_SHOW_ID = S.TV_SHOW_ID

How to Get All Rows matched + Unmatched and Unmatched Rows Column Will be null

I am working on an university management system. This is my database diagram
Database Diagram
I am creating a search form using this query:
SELECT Distinct
TblStudentBioData.RegNo,
TblStudentBioData.First_NameUr + SPACE(1)+ TblStudentBioData.Middle_NameUr + SPACE(1) + TblStudentBioData.Last_NameUr AS Name,
TblStudentBioData.Father_NameUr,
Ay.AcademicYearName,
Smst.SemName,
TBLCOLLEGE.CollegeName,
CID.ClassName,
TblImages.Images,
TblStudentBioData.Student_ID,
TblImages.ImageId,
Ay.AcademicYearId,
Smst.SemesterId,
TblClassSchedule.ClassSchId
FROM
TblStudentBioData
LEFT JOIN
TblStudentDetail ON (TblStudentBioData.Student_ID = TblStudentDetail.Student_ID)
OR (TblStudentBioData.Student_ID != TblStudentDetail.Student_ID)
INNER JOIN
TBLCFGSEX AS sex ON TblStudentBioData.CfgSexId = sex.CfgSexId
INNER JOIN
TBLMARITALSTATUS ON TblStudentBioData.MaritalStatusId = TBLMARITALSTATUS.MaritalStatusId
INNER JOIN
TblStudentSubAss ON TblStudentDetail.StudentDetailID = TblStudentSubAss.StudentDetailID
INNER JOIN
TblSubAss ON TblSubAss.SubAssId = TblStudentSubAss.SubAssId
INNER JOIN
TblClassSchedule ON TblStudentDetail.ClassSchId = TblClassSchedule.ClassSchID
INNER JOIN
TableClass AS CID ON TblClassSchedule.ClassID = CID.ClassID
INNER JOIN
TblImages ON TblStudentBioData.ImageId = TblImages.ImageId
LEFT JOIN
TBLCOLLEGE ON CID.CollegeId = TBLCOLLEGE.CollegeID
INNER JOIN
TBLBLOODGROUP BG On TblStudentBioData.BloodID = BG.BloodId
INNER JOIN
tableSemAssigning SA On TblClassSchedule.SemAssId = Sa.SemAssId
INNER JOIN
TblAcademicYear AY On SA.AcademicYearId = AY.AcademicYearId
INNER JOIN
TableSemester Smst On Smst.SemesterId = Sa.SemesterId
and this query gives me the output like this
In the result the 5th row is not matching row.
My question: how to show null value in non matching row's columns which I mention in the image?
As far as I can tell it would be like this. Anything that relates directly to TblStudentBioData MIGHT be an an INNER JOIN (I cannot tell) but everything that relates to TblStudentDetail should be a left join.
Also be careful with any where clause that you don't override these left joins.
SELECT DISTINCT /* I hate distinct, there is probably a better way */
TblStudentBioData.RegNo
, TblStudentBioData.First_NameUr + SPACE(1) + TblStudentBioData.Middle_NameUr + SPACE(1) + TblStudentBioData.Last_NameUr AS Name
, TblStudentBioData.Father_NameUr
, Ay.AcademicYearName
, Smst.SemName
, TBLCOLLEGE.CollegeName
, CID.ClassName
, TblImages.Images
, TblStudentBioData.Student_ID
, TblImages.ImageId
, Ay.AcademicYearId
, Smst.SemesterId
, TblClassSchedule.ClassSchId
FROM TblStudentBioData
INNER JOIN TBLCFGSEX AS sex
ON TblStudentBioData.CfgSexId = sex.CfgSexId
INNER JOIN TBLMARITALSTATUS
ON TblStudentBioData.MaritalStatusId = TBLMARITALSTATUS.MaritalStatusId
INNER JOIN TblImages
ON TblStudentBioData.ImageId = TblImages.ImageId
INNER JOIN TBLBLOODGROUP BG
ON TblStudentBioData.BloodID = BG.BloodId
LEFT JOIN TblStudentDetail
ON (TblStudentBioData.Student_ID = TblStudentDetail.Student_ID)
LEFT JOIN TblStudentSubAss
ON TblStudentDetail.StudentDetailID = TblStudentSubAss.StudentDetailID
LEFT JOIN TblClassSchedule
ON TblStudentDetail.ClassSchId = TblClassSchedule.ClassSchID
LEFT JOIN TblSubAss
ON TblSubAss.SubAssId = TblStudentSubAss.SubAssId
LEFT JOIN TableClass AS CID
ON TblClassSchedule.ClassID = CID.ClassID
LEFT JOIN TBLCOLLEGE
ON CID.CollegeId = TBLCOLLEGE.CollegeID
LEFT JOIN tableSemAssigning SA
ON TblClassSchedule.SemAssId = SA.SemAssId
LEFT JOIN TblAcademicYear AY
ON SA.AcademicYearId = AY.AcademicYearId
LEFT JOIN TableSemester Smst
ON Smst.SemesterId = SA.SemesterId