Multiple SQL JOIN with multiple criteria - sql

SELECT A.SspStudent,
B.StuLastName,
B.StuFirstName,
C.TerDescription,
A.SspCourseSubject,
A.SspCourseID,
A.SspCreditHours,
A.SspStatus,
B.StuEmailUNCW,
B.StuAdvisorEmail,
B.StuApplicationStatus,
D.UseName
FROM ((tblStudentSchedulePerm A
INNER JOIN tblStudent B
ON (A.SspStudent = B.StuID AND
B.StuAdmitTerm <> '201520A' AND
A.SspStatus = 'Schedul' AND
(A.SspTerm = '201520A' OR A.SspTerm = '201520B') AND
A.SspCreditHours <> 0))
LEFT OUTER JOIN tblTerms C
ON A.SspTerm = C.TerTermPart)
LEFT OUTER JOIN D tblUser
ON B.StuAdvisorEmail = D.UseEmail;
I am trying to make this query work but everytime I try to adjust the parenthesis I get an error.
Could I get some help??

you are better off, with out those parenthesis, also you need to a sub query in the joins
Retained the parenthesis except in the OR AND condition , try this out.
SELECT A.SspStudent,
B.StuLastName,
B.StuFirstName,
C.TerDescription,
A.SspCourseSubject,
A.SspCourseID,
A.SspCreditHours,
A.SspStatus,
B.StuEmailUNCW,
B.StuAdvisorEmail,
B.StuApplicationStatus,
D.UseName
FROM tblStudentSchedulePerm A
INNER JOIN tblStudent B
ON A.SspStudent = B.StuID
AND B.StuAdmitTerm <> '201520A'
AND A.SspStatus = 'Schedul'
AND ( A.SspTerm = '201520A'
OR A.SspTerm = '201520B' )
AND A.SspCreditHours <> 0
LEFT OUTER JOIN tblTerms C
ON A.SspTerm = C.TerTermPart
LEFT OUTER JOIN tblUser D
ON B.StuAdvisorEmail = D.UseEmail;

I indented your query. This is how I usually start to pick apart something with which I'm unfamilar.
SELECT
A.SspStudent
, B.StuLastName
, B.StuFirstName
, C.TerDescription
, A.SspCourseSubject
, A.SspCourseID
, A.SspCreditHours
, A.SspStatus
, B.StuEmailUNCW
, B.StuAdvisorEmail
, B.StuApplicationStatus
, D.UseName
FROM
(
(
tblStudentSchedulePerm A
INNER JOIN tblStudent B ON
(
A.SspStudent = B.StuID
AND B.StuAdmitTerm <> '201520A'
AND A.SspStatus = 'Schedul'
AND (A.SspTerm = '201520A' OR A.SspTerm = '201520B')
AND A.SspCreditHours <> 0
)
)
LEFT OUTER JOIN tblTerms C ON A.SspTerm = C.TerTermPart
)
LEFT OUTER JOIN D tblUser ON B.StuAdvisorEmail = D.UseEmail
;

D tblUser
should be :
tblUser D
Other than that, remove all useless parentheses:
SELECT A.SspStudent,
B.StuLastName,
B.StuFirstName,
C.TerDescription,
A.SspCourseSubject,
A.SspCourseID,
A.SspCreditHours,
A.SspStatus,
B.StuEmailUNCW,
B.StuAdvisorEmail,
B.StuApplicationStatus,
D.UseName
FROM tblStudentSchedulePerm A
INNER JOIN tblStudent B
ON A.SspStudent = B.StuID
AND B.StuAdmitTerm <> '201520A'
AND A.SspStatus = 'Schedul'
AND ( A.SspTerm = '201520A'
OR A.SspTerm = '201520B' )
AND A.SspCreditHours <> 0
LEFT OUTER JOIN tblTerms C
ON A.SspTerm = C.TerTermPart
LEFT OUTER JOIN tblUser D
ON B.StuAdvisorEmail = D.UseEmail;

Related

An SQL query with an 'IN' within the where clause is very slow to run

I have created an SQL query which runs but it takes about 17 seconds to complete. I have narrowed down the problem to the IN clause within the Where section of the query. This section is responsible for also finding all records within the same table where the kitref of one record matches the partofkit field of multiple other records.
Could anyone help with suggestions on how I may be able to make this more efficient?
The full SQL is below:
SELECT
tblProductions.ProductionName, tblEquipment.KitRef, tblEquipment.PartOfKit, tblEquipment.Description,
tblCollection.HireID, tblCollection.CollectedBy, Format(tblCollection.DueBack,'dd/MM/yyyy') AS DueBack, Format(tblCollection.CollectionDate,'dd/MM/yyyy') AS CollectionDate, Format(tblCollection.CollectionTime,'HH:mm') AS CollectionTime, tblCollection.DiscountPC,
tblCollectionItemized.HireLine, tblCollectionItemized.Notes, tblCollectionItemized.BookingActive, tblCollectionItemized.DepositReturned, tblTariff.Tariff
FROM tblTariff
INNER JOIN (
tblProductions INNER JOIN (
tblCollection INNER JOIN (
tblEquipment
INNER JOIN tblCollectionItemized ON tblEquipment.KitKey = tblCollectionItemized.KitKey
) ON tblCollection.HireID = tblCollectionItemized.HireID)
ON tblProductions.ProductionIDKey = tblCollection.ProductionName
) ON tblTariff.TariffKey = tblCollection.Tarriff
WHERE (
tblCollectionItemized.BookingActive='TRUE'
AND tblEquipment.PartOfKit IN (
SELECT tblEquipment.KitRef
FROM tblEquipment
INNER JOIN tblCollectionItemized ON tblEquipment.KitKey = tblCollectionItemized.KitKey
WHERE tblCollectionItemized.ReturnsNumber =43
)
)
OR (
tblCollectionItemized.BookingActive='TRUE'
AND tblCollectionItemized.ReturnsNumber =43
)
Not a complete answer here but using some aliases and joins in a logical order make this nightmarish query into something a lot easier to see what is going on.
SELECT
p.ProductionName
, e.KitRef
, e.PartOfKit
, e.Description
, c.HireID
, c.CollectedBy
, Format(c.DueBack,'dd/MM/yyyy') AS DueBack
, Format(c.CollectionDate,'dd/MM/yyyy') AS CollectionDate
, Format(c.CollectionTime,'HH:mm') AS CollectionTime
, c.DiscountPC
, ci.HireLine
, ci.Notes
, ci.BookingActive
, ci.DepositReturned
, t.Tariff
FROM tblTariff t
INNER JOIN tblCollection c ON t.TariffKey = c.Tarriff
INNER JOIN tblProductions p ON p.ProductionIDKey = c.ProductionName
INNER JOIN tblCollectionItemized ci ON c.HireID = ci.HireID
INNER JOIN tblEquipment e ON e.KitKey = ci.KitKey
WHERE ci.BookingActive = 'TRUE'
AND e.PartOfKit IN
(
SELECT e2.KitRef
FROM tblEquipment e2
INNER JOIN tblCollectionItemized ci2 ON e2.KitKey = ci2.KitKey
WHERE ci2.ReturnsNumber = 43
)
OR
(
ci.ReturnsNumber = 43
)
you can try EXISTS instead of IN and add (nolock) hint to tables
SELECT
P.ProductionName,
E.KitRef,
E.PartOfKit,
E.Description,
C.HireID,
C.CollectedBy,
Format(C.DueBack,'dd/MM/yyyy') AS DueBack,
Format(C.CollectionDate,'dd/MM/yyyy') AS CollectionDate,
Format(C.CollectionTime,'HH:mm') AS CollectionTime,
C.DiscountPC,
CI.HireLine,
CI.Notes,
CI.BookingActive,
CI.DepositReturned,
T.Tariff
FROM tblTariff T
INNER JOIN tblCollection C (nolock) ON T.TariffKey = C.Tarriff
INNER JOIN tblProductions P (nolock) ON P.ProductionIDKey = C.ProductionName
INNER JOIN tblCollectionItemized CI (nolock) ON C.HireID = CI.HireID
INNER JOIN tblEquipment E (nolock) ON E.KitKey = CI.KitKey
WHERE (
tblCollectionItemized.BookingActive='TRUE'
AND EXISTS (
SELECT *
FROM tblEquipment E2 (nolock)
INNER JOIN tblCollectionItemized CI2 (nolock) ON E2.KitKey = CI2.KitKey
WHERE CI2.ReturnsNumber =43 AND E.PartOfKit = E2.KitRef )
)
OR (
CI.BookingActive='TRUE'
AND CI.ReturnsNumber =43
)

using a subquery as a column that's using another column in the 'where' clause

I probably messed that title up! So I have a column called "programID" and I want another column to tell me the most recent date an order was placed using the programID. I think I'd need a subcolumn but the problem is how do I use the row's programID so that it matches the programID for the same row?
DECLARE #ClientIDs varchar(4) = 6653;
DECLARE #ProgramStatus char(1) = 'Y'; -- Y, N, or R
SELECT
rcp.RCPID AS ProgramID
, rcp.RCPName AS Program
, rcp.RCPActive AS ProgramStatus
, aa.AACustomCardInternalReview AS VCCP
, aa.AAJobNo AS AAJobNo
, aas.AASName AS AAStatus
, rcp.RCPOpsApproved AS OpsApproved
, clt.CltID AS ClientID
, rcp.RCPSignatureRequired AS SignatureRequired
, st.STEnumValue AS DefaultShipType
, rcp.RCPShipMethodOverrideType AS ShipTypeOverride
,aa.AANetworkProgramID
,(Select max(cdconfirmationdate) from carddet where ) --can't figure this part out
FROM
RetailerCardProgram rcp WITH (NOLOCK)
INNER JOIN ClientRetailerMap crm WITH (NOLOCK)
ON crm.CRMRetailerID = rcp.RCPRetailerID
INNER JOIN Client clt WITH(NOLOCK)
ON clt.CltID = crm.CRMCltID
LEFT JOIN AssociationApproval aa WITH (NOLOCK)
ON aa.AARetailerID = rcp.RCPRetailerID
AND aa.AABin = rcp.RCPBin6
AND aa.AAFrontOfPlasticTemplateID = rcp.RCPFOCTemplateID
AND aa.AABackOfPlasticTemplateID = rcp.RCPBOCTemplateID
AND ISNULL(aa.AACardID, 0) = ISNULL(rcp.RCPDefaultPlasticCardID, 0)
-- AND LOWER(rcp.RCPName) NOT LIKE '%do not use%' -- Needed for AA Job Number 1594
LEFT JOIN AssociationApprovalStatus aas WITH (NOLOCK)
ON aas.AASID = aa.AAAssociationApprovalStatusID
LEFT JOIN OpenLoopAssociation ola WITH (NOLOCK)
ON ola.OLAID=rcp.RCPOLAID
LEFT JOIN ClientCardProgramMap ccpm WITH (NOLOCK)
ON ccpm.CCPMCardProgramID = rcp.RCPID
AND ccpm.CCPMClientID = clt.CltID
LEFT JOIN TippingModule tm WITH (NOLOCK)
ON tm.TMid = rcp.RCPTippingModuleID
LEFT JOIN GiftCardTemplate fgt WITH (NOLOCK)
ON fgt.gtid = rcp.RCPFOCTemplateID
AND fgt.GTPage='P'
LEFT JOIN GiftCardTemplate bgt WITH (NOLOCK)
ON bgt.gtid = rcp.RCPBOCTemplateID
AND bgt.GTPage='PB'
LEFT JOIN Card c WITH (NOLOCK)
ON c.CardID = rcp.RCPDefaultCarrierID
LEFT JOIN CardType ct WITH (NOLOCK)
ON ct.CTID = c.CardTypeID
LEFT JOIN RetailerCardProgramTCSheetMap rtm1 WITH (NOLOCK)
ON rtm1.RTMRCPID = rcp.RCPID
AND rtm1.RTMInsertOrder = 1
LEFT JOIN RetailerCardProgramTCSheetMap rtm2 WITH (NOLOCK)
ON rtm2.RTMRCPID = rcp.RCPID
AND rtm2.RTMInsertOrder = 2
LEFT JOIN RetailerCardProgramTCSheetMap rtm3 WITH (NOLOCK)
ON rtm3.RTMRCPID = rcp.RCPID
AND rtm3.RTMInsertOrder = 3
LEFT JOIN RetailerCardProgramTCSheetMap rtm4 WITH (NOLOCK)
ON rtm4.RTMRCPID = rcp.RCPID
AND rtm4.RTMInsertOrder = 4
LEFT JOIN TCSheet i1 WITH (NOLOCK)
ON i1.TCSID = rtm1.RTMTCSID
LEFT JOIN TCSheet i2 WITH (NOLOCK)
ON i2.TCSID = rtm2.RTMTCSID
LEFT JOIN TCSheet i3 WITH (NOLOCK)
ON i3.TCSID = rtm3.RTMTCSID
LEFT JOIN TCSheet i4 WITH (NOLOCK)
ON i4.TCSID = rtm4.RTMTCSID
LEFT JOIN ShipType st WITH (NOLOCK)
ON st.STId = rcp.RCPDefaultShipTypeID
WHERE
clt.CltID IN (#ClientIDs) -- 6653 and 6657.
AND rcp.RCPActive IN (#ProgramStatus)
ORDER BY
AAJobNo
, Program
You want to join with a nested select on the table carddet. I'm inferring that RCPID is the relationship between carddet and your main table RetainerCardProgram...
SELECT rcp.RCPID AS ProgramID,
date.MAXDATE AS MaxDate,
rest of your columns...
FROM RetailerCardProgram rcp WITH (NOLOCK)
INNER JOIN (
SELECT RCPID, MAX(cdconfirmationdate) as 'MAXDATE'
FROM carddet
GROUP BY RCPID
) date on date.RCPID = rcp.RCPID
rest of query...
You may want a left join if not all IDs have a date in carddet.
Obligatory addition: Also your use of NOLOCK is a bit terrifying. See http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/

Optimize query contains too many inner join and rows

I have the following query
SELECT *
INTO ##TempStaffT
FROM Staff HF
WHERE HF.[businessline_id]='T'
AND HF.[offices_id] IN (SELECT * FROM ##TempParamOffice)
AND HF.[specialism_id]IN (SELECT * FROM ##TempParamSpecialism)
AND HF.[onetouch]IN (SELECT * FROM ##TempParamConsultant)
SET #sql4 = N'
INSERT INTO ##TempFees(' + #columns1 + ',CALF_AN ,BusinessName)
SELECT distinct ' + #columns2 + ',p.CALF_AN ,CB.[TempBusinessName] as BusinessName
FROM
dbo.WTEFAC EF
inner JOIN dbo.WTFAC F ON EF.EFAC_NUM = F.EFAC_NUM
inner JOIN dbo.WTFACINFO BS ON F.FAC_NUM = BS.FAC_NUM
inner JOIN dbo.WTLFAC LF ON F.FAC_NUM = LF.FAC_NUM
inner JOIN dbo.WTRUBVARIANTEFAC WRU ON LF.RINT_ID = WRU.RINT_ID
inner JOIN dbo.WTACUMFAC WTA ON WRU.RUV_ID = WTA.RUV_ID
inner JOIN ##CUM_CODEHT WTA1 ON WTA.CUM_ID = WTA1.CUM_ID
inner JOIN dbo.WTVTAT TAT ON BS.TIE_ID = TAT.TIE_ID AND BS.RFAN_ID = TAT.RFAN_ID AND BS.PER_ID = TAT.PER_ID AND BS.CNT_ID = TAT.CNT_ID
inner JOIN dbo.PYCONTRAT CC ON TAT.PER_ID = CC.PER_ID AND TAT.CNT_ID = CC.CNT_ID
inner JOIN dbo.WTMISS M ON CC.PER_ID = M.PER_ID AND CC.CNT_ID = M.CNT_ID
inner JOIN dbo.WTCNTI COT1 ON M.PER_ID = COT1.PER_ID AND M.CNT_ID = COT1.CNT_ID
inner JOIN dbo.WTQUAEU Q ON COT1.TIE_ID = Q.TIE_ID AND COT1.QEU_CDE = Q.QEU_CDE
inner JOIN dbo.WTSCCT C ON CC.RGPCNT_ID = C.RGPCNT_ID AND CC.PER_ID = C.PER_ID AND CC.CNT_ID = C.CNT_ID --AND''SECT3'' = C.STTQ_COD
INNER JOIN ##TempStaffT HF ON C.VAPO_CODE = HF.onetouch COLLATE Latin1_General_CI_AS
inner JOIN
##TempA AS p ON p.CNT_ID = COT1.CNT_ID inner JOIN
##TempB AS p1 ON p1.CNT_ID = COT1.CNT_ID
CROSS JOIN [dbo].[CustBusinessTable] CB
WHERE CB.[TempBusinessName]=''Pure Temp Fees''
GROUP BY p.CALF_AN,CB.[TempBusinessName]
'
;
PRINT #sql4;
My problem is that the query above took 20 min to be executed because ##TempStaffT contains too many rows , how can I optimize it ? I use many temp tables but it seems not to be worked , Any idea ? Many thanks in advance .
Create an index on ##TempStaffT
CREATE INDEX IDX_TempStaffT_onetouch ON ##TempStaffT(onetouch)

How can I use the group by Clause in a subquery

I just need to select one more field in my query that is the date... but it's a subquery and i'm using a count field... and because of it i need to use the GROUP BY Clause... But i can't group by my subquery and the query is returning errors...
SELECT
X.NROF,
Z.NMGUERFORN,
C.CDCOMPRADO,
C.CDCOORDENA,
E.CDFUP,
count(*) AS ocorrencias
--(select TOP 1 DTPROGENTR from CMPENL0 C (NOLOCK) where X.NRPEDICOMP = C.NRPEDICOMP AND X.NRITEMPECO = C.NRITEMPECO) AS DTPROGENTR
FROM CMPCIL0 X (NOLOCK)
inner join CMPCCL0 Y (NOLOCK) on X.NRPEDICOMP = Y.NRPEDICOMP
inner join CMFRNL0 Z (NOLOCK) on Y.CDFORNECED1 = Z.CDFORNECED1
inner join CMSCPL0 M (NOLOCK) on X.NRSOLICOMP = M.NRSOLICOMP AND X.NRITEMSC = M.NRITEMSC
inner join CMPENL0 N (NOLOCK) on X.NRPEDICOMP = N.NRPEDICOMP AND X.NRITEMPECO = N.NRITEMPECO
inner join CMMATL0 A (NOLOCK) on X.CDMATERIAL = A.CDMATERIAL
inner join cmcomL0 c (NOLOCK) on c.cdcomprado = y.cdcomprado
LEFT JOIN AMCSPL0 D (NOLOCK) ON D.SCPE_NRSOLICOMP = X.NRSOLICOMP AND D.SCPE_NRITEMSC=X.NRITEMSC
LEFT JOIN CMFUPL0 E (NOLOCK) ON E.CDFORNECED1 = Z.CDFORNECED1
LEFT JOIN CMPFIL0 H ON Z.CDFORNECED1 = H.CDFORNECED1 AND X.NRIDENTIFI = H.NRIDENTIFI and H.DTVALIDADE > Y.DTEFETPECO
LEFT JOIN CMPENL0 F ON (X.NRPEDICOMP = F.NRPEDICOMP AND X.NRITEMPECO = F.NRITEMPECO)
WHERE X.CDSTATUS = 'P' and X.NROF <> 0
group by X.NROF,Z.NMGUERFORN,C.CDCOMPRADO,C.CDCOORDENA,E.CDFUP--,DTPROGENTR
order by 6 desc
The commented parts are the code im trying to include to select the field, but it is giving me errors..
The problem is that you use aliases in your where clause of select sub-query. Aliases cannot be referenced on the same level in the query. You should use full qualified names and the sub-query should look something like that:
(select TOP 1 DTPROGENTR from CMPENL0 C (NOLOCK) where X.NRPEDICOMP = CMPENL0.NRPEDICOMP AND X.NRITEMPECO = CMPENL0.NRITEMPECO) AS DTPROGENTR
If your sql-server supports common table expressions you can try that:
;WITH cte AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY NRPEDICOMP, NRITEMPECO ORDER BY NRPEDICOMP) row_num
,DTPROGENTR
,NRPEDICOMP
,NRITEMPECO
FROM CMPENL0 (NOLOCK)
)
SELECT
X.NROF,
Z.NMGUERFORN,
C.CDCOMPRADO,
C.CDCOORDENA,
E.CDFUP,
count(*) AS ocorrencias
cte.DTPROGENTR
FROM CMPCIL0 X (NOLOCK)
inner join CMPCCL0 Y (NOLOCK) on X.NRPEDICOMP = Y.NRPEDICOMP
inner join CMFRNL0 Z (NOLOCK) on Y.CDFORNECED1 = Z.CDFORNECED1
inner join CMSCPL0 M (NOLOCK) on X.NRSOLICOMP = M.NRSOLICOMP AND X.NRITEMSC = M.NRITEMSC
inner join CMPENL0 N (NOLOCK) on X.NRPEDICOMP = N.NRPEDICOMP AND X.NRITEMPECO = N.NRITEMPECO
inner join CMMATL0 A (NOLOCK) on X.CDMATERIAL = A.CDMATERIAL
inner join cmcomL0 c (NOLOCK) on c.cdcomprado = y.cdcomprado
LEFT JOIN AMCSPL0 D (NOLOCK) ON D.SCPE_NRSOLICOMP = X.NRSOLICOMP AND D.SCPE_NRITEMSC=X.NRITEMSC
LEFT JOIN CMFUPL0 E (NOLOCK) ON E.CDFORNECED1 = Z.CDFORNECED1
LEFT JOIN CMPFIL0 H ON Z.CDFORNECED1 = H.CDFORNECED1 AND X.NRIDENTIFI = H.NRIDENTIFI and H.DTVALIDADE > Y.DTEFETPECO
LEFT JOIN CMPENL0 F ON X.NRPEDICOMP = F.NRPEDICOMP AND X.NRITEMPECO = F.NRITEMPECO
LEFT JOIN cte ON X.NRPEDICOMP = cte.NRPEDICOMP AND X.NRITEMPECO = cte.NRITEMPECO AND cte.row_num = 1
WHERE X.CDSTATUS = 'P' and X.NROF <> 0
group by X.NROF,Z.NMGUERFORN,C.CDCOMPRADO,C.CDCOORDENA,E.CDFUP, cte.DTPROGENTR
order by 6 desc

LEFT OUTER JOIN 3 tables

I'm updating queries that were using the old construction for outer joins (=* and *=). I have 3 tables that I need to include in an outer join.
The original query is:
SELECT s.SkillID ,
NULL AS Signature ,
NULL AS DPL ,
CASE WHEN ISNULL(ds.DPL, dg.DPL) IS NULL
THEN p.ScaleTo - p.ScaleFrom + 1
ELSE ISNULL(ds.DPL, dg.DPL)
END AS DefaultDPL
FROM tbJobs j ,
tbSkills s
INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID ,
tbPerfScales p ,
tbDPLs ds ,
tbDPLs dg
WHERE j.JobID = 866
AND ( ds.LevelID=*j.LevelID
AND ds.IDType = 1
AND ds.GroupOrSkillID=*s.SkillID
)
AND ( dg.LevelID=*j.LevelID
AND dg.IDType = 0
AND dg.GroupOrSkillID=*sg.SkillGroupID
)
AND ( ( s.PerfScaleID IS NOT NULL
AND p.PerfScaleID = s.PerfScaleID
)
OR ( s.PerfScaleID IS NULL
AND p.PerfScaleID = sg.PerfScaleID
)
)
I'm doing:
SELECT s.SkillID ,
NULL AS Signature ,
NULL AS DPL ,
CASE WHEN ISNULL(ds.DPL, dg.DPL) IS NULL
THEN p.ScaleTo - p.ScaleFrom + 1
ELSE ISNULL(ds.DPL, dg.DPL)
END AS DefaultDPL
FROM tbPerfScales p ,
tbSkills s
INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID ,
tbJobs j
LEFT OUTER JOIN tbDPLs ds ON j.LevelID = ds.LevelID
AND s.SkillID = ds.GroupOrSkillID
LEFT OUTER JOIN tbDPLs dg ON j.LevelID = dg.LevelID
AND sg.SkillGroupID = dg.GroupOrSkillID
WHERE j.JobID = 866
AND ds.IDType = 1
AND dg.IDType = 0
AND ( ( s.PerfScaleID IS NOT NULL
AND p.PerfScaleID = s.PerfScaleID
)
OR ( s.PerfScaleID IS NULL
AND p.PerfScaleID = sg.PerfScaleID
)
)
For some reason I'm getting the error:
The multi-part identifier "s.SkillID" could not be bound.
And I know is in this part:
tbJobs j
LEFT OUTER JOIN tbDPLs ds ON j.LevelID = ds.LevelID
AND s.SkillID = ds.GroupOrSkillID
I'm not sure what I'm doing wrong.
Thanks any help.
Jose
There is a comma after the statement
INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID ,
Which is because you have tbJobs after it, when it should be in the other tables. I would recommend using CROSS JOIN instead of just having multiple tables in the FROM clause as it will be more clear.
Here is the base rewrite of your query that should work, though you should be able to easily get rid of most of the cross joins.
SELECT s.SkillID ,
NULL AS Signature ,
NULL AS DPL ,
CASE WHEN ISNULL(ds.DPL, dg.DPL) IS NULL
THEN p.ScaleTo - p.ScaleFrom + 1
ELSE ISNULL(ds.DPL, dg.DPL)
END AS DefaultDPL
FROM tbPerfScales p
CROSS JOIN tbSkills s
CROSS JOIN tbJobs j
INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID
LEFT OUTER JOIN tbDPLs ds ON j.LevelID = ds.LevelID
AND s.SkillID = ds.GroupOrSkillID
LEFT OUTER JOIN tbDPLs dg ON j.LevelID = dg.LevelID
AND sg.SkillGroupID = dg.GroupOrSkillID
WHERE j.JobID = 866
AND ds.IDType = 1
AND dg.IDType = 0
AND ( ( s.PerfScaleID IS NOT NULL
AND p.PerfScaleID = s.PerfScaleID
)
OR ( s.PerfScaleID IS NULL
AND p.PerfScaleID = sg.PerfScaleID
)
)
You cannot mix the different SQL syntax. If you are going with ANSI-92 you need to correct all the joins, not just the outer joins. Consistency is key.
The comma is the incorrect syntax now. You need to add a join for each table, or pull them out into cross applies per Darren's answer.
This is the issue:
FROM tbPerfScales p ,
tbSkills s
INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID ,
tbJobs j
LEFT OUTER JOIN tbDPLs ds ON j.LevelID = ds.LevelID
AND s.SkillID = ds.GroupOrSkillID
LEFT OUTER JOIN tbDPLs dg ON j.LevelID = dg.LevelID
AND sg.SkillGroupID = dg.GroupOrSkillID
it needs to be along the lines of:
FROM tbPerfScales p
INNER JOIN tbSkills s ON p.<field> = s.<field>
INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID
INNER JOIN tbJobs j on j.<field> = <table p? sg? not sure>.<field>
LEFT OUTER JOIN tbDPLs ds ON j.LevelID = ds.LevelID
AND s.SkillID = ds.GroupOrSkillID
LEFT OUTER JOIN tbDPLs dg ON j.LevelID = dg.LevelID
AND sg.SkillGroupID = dg.GroupOrSkillID