I'm trying to optimize a SQL query but I face a weird issue.
Here is my optimized request :
SELECT proj.ProjetId AS ProjetId,
SUM (CASE WHEN modTrans.Code != 'FoO' THEN 1 ELSE 0 END) AS VAL1,
SUM(CASE WHEN modTrans.Code = 'Foo' THEN 1 ELSE 0 END) AS VAL2
FROM Projet.Projet proj
INNER JOIN Workflow.PointControle ptCont
ON ptCont.ProjetId = proj.ProjetId
INNER JOIN Workflow.PointControleModele ptContMod
ON ptContMod.PointControleModeleId = ptCont.PointControleModeleId
INNER JOIN Commande.CommandeTAC cdeTAC
ON cdeTAC.ProjetId = proj.ProjetId
INNER JOIN Commande.CommandeTACCatalogue cdeTACCat
ON cdeTACCat.CommandeTACId = cdeTAC.CommandeTACId
INNER JOIN Fournisseur.Fournisseur four
ON four.FournisseurId = cdeTACCat.FournisseurId
INNER JOIN Fournisseur.ModeTransmission modTrans
ON modTrans.ModeTransmissionId = four.ModeTransmissionId
WHERE ptContMod.PointControleModeleCode = 'FFooooooooo'
AND ptCont.Etat = 'Foooooo'
AND proj.DateLivraison IS NOT NULL
AND [proj].[DateLivraison] <= DATEADD(DAY, 14, GETDATE())
GROUP BY proj.ProjetId
HAVING COUNT(VAL1) > 0 AND COUNT(VAL2) = 0
I got this error :
Column name invalid : 'VAL1' Column name invalid : 'VAL2'
The error is in the HAVING section.
After reading this documentation I dont undestand why there is an error because I respect the syntax : http://www.w3schools.com/sql/sql_having.asp
You can find the unoptimized complete request here :
BEGIN
WITH Trans(VAL1, VAL2, projetId) AS
(
SELECT SUM (CASE WHEN modTrans.Code != 'Foo' THEN 1 ELSE 0 END) AS NbNonSALM
, SUM(CASE WHEN modTrans.Code = 'Foo' THEN 1 ELSE 0 END) AS NbSALM
, proj.ProjetId AS projetId
FROM Projet.Projet proj
INNER JOIN Workflow.PointControle ptCont
ON ptCont.ProjetId = proj.ProjetId
INNER JOIN Workflow.PointControleModele ptContMod
ON ptContMod.PointControleModeleId = ptCont.PointControleModeleId
INNER JOIN Commande.CommandeTAC cdeTAC
ON cdeTAC.ProjetId = proj.ProjetId
INNER JOIN Commande.CommandeTACCatalogue cdeTACCat
ON cdeTACCat.CommandeTACId = cdeTAC.CommandeTACId
INNER JOIN Fournisseur.Fournisseur four
ON four.FournisseurId = cdeTACCat.FournisseurId
INNER JOIN Fournisseur.ModeTransmission modTrans
ON modTrans.ModeTransmissionId = four.ModeTransmissionId
WHERE ptContMod.PointControleModeleCode = 'Foooooo'
AND ptCont.Etat = 'Fooo'
AND proj.DateLivraison IS NOT NULL
AND DATEADD(DAY, -14, proj.DateLivraison) <= GETDATE()
GROUP BY proj.ProjetId
)
SELECT proj.ProjetId AS ProjetId
FROM Projet.Projet proj
INNER JOIN Workflow.PointControle ptCont
ON ptCont.ProjetId = proj.ProjetId
INNER JOIN Workflow.PointControleModele ptContMod
ON ptContMod.PointControleModeleId = ptCont.PointControleModeleId
INNER JOIN Commande.CommandeTAC cdeTAC
ON cdeTAC.ProjetId = proj.ProjetId
INNER JOIN Commande.CommandeTACCatalogue cdeTACCat
ON cdeTACCat.CommandeTACId = cdeTAC.CommandeTACId
INNER JOIN Fournisseur.Fournisseur four
ON four.FournisseurId = cdeTACCat.FournisseurId
INNER JOIN Fournisseur.ModeTransmission modTrans
ON modTrans.ModeTransmissionId = four.ModeTransmissionId
INNER JOIN Trans ON Trans.projetId = proj.ProjetId
WHERE ptContMod.PointControleModeleCode = 'Foo'
AND ptCont.Etat = 'Fooo'
AND proj.DateLivraison IS NOT NULL
AND DATEADD(DAY, -14, proj.DateLivraison) <= GETDATE()
GROUP BY proj.ProjetId
HAVING COUNT(trans.NbNonSALM) > 0 AND COUNT(trans.NbSALM) = 0
UNION
SELECT projet.ProjetId AS ProjetId
FROM Projet.Projet projet
INNER JOIN Workflow.PointControle ptControle
ON ptControle.ProjetId = projet.ProjetId
INNER JOIN Workflow.PointControleModele ptContMod
ON ptContMod.PointControleModeleId = ptControle.PointControleModeleId
INNER JOIN Commande.CommandeTAC cdeTAC
ON cdeTAC.ProjetId = projet.ProjetId
INNER JOIN Commande.CommandeTACCatalogue cdeTACCat
ON cdeTACCat.CommandeTACId = cdeTAC.CommandeTACId
INNER JOIN commande.AREntete arEnt
ON arEnt.ProjetIdTAC = cdeTAC.ProjetIdTAC
INNER JOIN Commande.Article art
ON art.AREnteteId = arEnt.AREnteteId AND art.CommandeTACCatalogueId = cdeTACCat.CommandeTACCatalogueId
INNER JOIN Fournisseur.Fournisseur four
ON four.FournisseurId = cdeTACCat.FournisseurId
INNER JOIN Fournisseur.ModeTransmission modTrans
ON modTrans.ModeTransmissionId = four.ModeTransmissionId
WHERE ptContMod.PointControleModeleCode = 'Fooo'
AND ptControle.Etat = 'Foo'
AND arEnt.SuppressionLogique = 0
AND arEnt.Statut IS NOT NULL
AND arEnt.Statut >= 4
AND arEnt.Statut != 9
AND modTrans.Code = 'Fooooooo'
AND projet.SiteId = #siteId
END
;
I am not try this, but I think it work for you.. Or you can give some sample data if error comes.
;WITH CTE AS
(
SELECT proj.ProjetId AS ProjetId,
SUM (CASE WHEN modTrans.Code != 'FoO' THEN 1 ELSE 0 END) AS VAL1,
SUM(CASE WHEN modTrans.Code = 'Foo' THEN 1 ELSE 0 END) AS VAL2
FROM Projet.Projet proj
INNER JOIN Workflow.PointControle ptCont
ON ptCont.ProjetId = proj.ProjetId
INNER JOIN Workflow.PointControleModele ptContMod
ON ptContMod.PointControleModeleId = ptCont.PointControleModeleId
INNER JOIN Commande.CommandeTAC cdeTAC
ON cdeTAC.ProjetId = proj.ProjetId
INNER JOIN Commande.CommandeTACCatalogue cdeTACCat
ON cdeTACCat.CommandeTACId = cdeTAC.CommandeTACId
INNER JOIN Fournisseur.Fournisseur four
ON four.FournisseurId = cdeTACCat.FournisseurId
INNER JOIN Fournisseur.ModeTransmission modTrans
ON modTrans.ModeTransmissionId = four.ModeTransmissionId
WHERE ptContMod.PointControleModeleCode = 'FFooooooooo'
AND ptCont.Etat = 'Foooooo'
AND proj.DateLivraison IS NOT NULL
AND [proj].[DateLivraison] <= DATEADD(DAY, 14, GETDATE())
GROUP BY proj.ProjetId
)
SELECT ProjetId, VAL1, VAL2
FROM CTE
GROUP BY ProjetId, VAL1, VAL2
HAVING COUNT(VAL1) > 0 AND COUNT(VAL2) = 0
You cannot use the alias in the HAVING clause. Replace with this instead:
HAVING
SUM(CASE WHEN modTrans.Code != 'FoO' THEN 1 ELSE 0 END) > 0
AND SUM(CASE WHEN modTrans.Code = 'Foo' THEN 1 ELSE 0 END) = 0
Replace your HAVING clause with this
HAVING
SUM (CASE WHEN modTrans.Code != 'FoO' THEN 1 ELSE 0 END)>0
AND
SUM(CASE WHEN modTrans.Code = 'Foo' THEN 1 ELSE 0 END)=0
Related
I would like the results to produce a new row in each instance where a condition is met. I'm using a CASE statement but this isn't the way to go since once the first condition is met it stops evaluating the field.
SELECT
Reviews.ReviewID,
CASE
WHEN Score_CorrectID = 0 THEN 'Correct ID Right Party Authentication'
WHEN Score_ProperlyIdentified = 0 THEN 'PCA Properly Identified Itself'
WHEN Score_MiniMiranda = 0 THEN 'Mini-Miranda'
END AS [Error Type]
FROM Reviews INNER JOIN PCAs ON Reviews.PCAID = PCAs.PCAID LEFT JOIN
PCARebuttal ON Reviews.ReviewID = PCARebuttal.ReviewID
WHERE
(Score_CorrectID = 0 OR Score_ProperlyIdentified = 0 OR Score_MiniMiranda =
0)
This produces this:
I would like this:
Use apply:
SELECT r.ReviewID, v.error_type
FROM Reviews r INNER JOIN
PCAs
ON r.PCAID = PCAs.PCAID LEFT JOIN
PCARebuttal pr
ON r.ReviewID = pr.ReviewID OUTER APPLY
(SELECT *
FROM (VALUES (Score_CorrectID, 'Correct ID Right Party Authentication'),
(Score_ProperlyIdentified, 'PCA Properly Identified Itself'),
(Score_MiniMiranda, 'Mini-Miranda')
) v(score, error_type)
WHERE score = 0
) v
WHERE (Score_CorrectID = 0 OR Score_ProperlyIdentified = 0 OR Score_MiniMiranda = 0);
That said, I would probably just concatenate the values into a single column:
SELECT r.ReviewID,
( (CASE WHEN Score_CorrectID = 0 THEN 'Correct ID Right Party Authentication; ' ELSE '' END) +
(CASE WHEN Score_ProperlyIdentified = 0 THEN 'PCA Properly Identified Itself; ' ELSE '' END) +
(CASE WHEN Score_MiniMiranda = 0 THEN 'Mini-Miranda;' ELSE '' END)
) as error_types
FROM Reviews r INNER JOIN
PCAs
ON r.PCAID = PCAs.PCAID LEFT JOIN
PCARebuttal pr
ON r.ReviewID = pr.ReviewID OUTER APPLY
(SELECT *
FROM (VALUES ()
) v(score, error_type)
WHERE score = 0
) v
WHERE (Score_CorrectID = 0 OR Score_ProperlyIdentified = 0 OR Score_MiniMiranda = 0);
Instead of using case, you can use union all instead:
SELECT
Reviews.ReviewID,
'Correct ID Right Party Authentication' AS [Error Type]
FROM Reviews
INNER JOIN PCAs ON Reviews.PCAID = PCAs.PCAID
LEFT JOIN PCARebuttal ON Reviews.ReviewID = PCARebuttal.ReviewID
WHERE Score_CorrectID = 0
UNION ALL
SELECT
Reviews.ReviewID,
'PCA Properly Identified Itself' AS [Error Type]
FROM Reviews
INNER JOIN PCAs ON Reviews.PCAID = PCAs.PCAID
LEFT JOIN PCARebuttal ON Reviews.ReviewID = PCARebuttal.ReviewID
WHERE Score_ProperlyIdentified = 0
UNION ALL
SELECT
Reviews.ReviewID,
'Mini-Miranda' AS [Error Type]
FROM Reviews
INNER JOIN PCAs ON Reviews.PCAID = PCAs.PCAID
LEFT JOIN PCARebuttal ON Reviews.ReviewID = PCARebuttal.ReviewID
WHERE Score_MiniMiranda = 0
I have the below query , If the table data grows and contained millions of record , would it cause performance issue ? can it be enhanced in a way I dont run select count() in the select several time ? I already added index on the 6 columns.
I know the join is bad I am already enhancing the query
SELECT
P.CID,
P.CB,
(SELECT COUNT(1)
FROM EED_TABLE F
WHERE F.ID = P.ID
AND F.BC = P.BC
AND F.PCD = P.PCD
AND F.CID = P.CID
AND F.BRC = P.BRC
AND F.ST = 'F') ST_F,
(SELECT COUNT(1)
FROM EED_TABLE N
WHERE N.ID = P.ID
AND N.BC = P.BC
AND N.PCD = P.PCD
AND N.COMP_CODE = P.COMP_CODE
AND N.BRC = P.BRC
AND N.ST = 'N') ST_N,
(SELECT COUNT(1)
FROM EED_TABLE A
WHERE A.ID = P.ID
AND A.BC = P.BC
AND A.PCD = P.PCD
AND A.CID = P.CID
AND F.BRC = P.BRC
AND A.ST = 'A') ST_A
FROM EED_TABLE P ,EDD_DEF D
WHERE P.PCD = D.PCD
AND P.BC= D.BC
AND P.CD= 1
AND P.ID = 1
AND P.BC= 22
AND P.PCD = 31
I always prefer to go for JOIN instead of having more select statements, this is how I would do it, not knowing your data of course so maybe it won't work, but give it a shot and let me know of results and speed
select
p.cid, p.cb, SUM(case when f.id is not null then 1 else 0 end) st_f,
, SUM(case when a.id is not null then 1 else 0 end) st_a
, SUM(case when n.id is not null then 1 else 0 end) st_n
from eed_table p
join edd_def d on p.pcd = d.pcd and p.bc = d.bc
left join eed_table f on f.id = p.id and f.bc = p.bc
and f.pcd = p.pcd and f.cid = p.cid
and f.brc = p.brc and f.st = 'f'
left join eed_table a on p.id = a.id and p.bc = a.bc
and p.pcd = a.pcd and p.cid = a.cid
and p.brc = a.brc and a.st = 'a'
left join eed_table n on n.id = p.id and n.bc = p.bc
and n.pcd = p.pcd and n.comp_code = p.comp_code
and n.brc = p.brc and n.st = 'n'
where p.cd = 1 and p.id = 1 and p.bc = 22 and p.pcd = 31
group by p.cid, p.cb
Seems that your query can be rewritten with window functions as:
SELECT
DISTINCT P.CID, P.CB
, SUM(CASE WHEN P.ST = 'F' THEN 1 ELSE 0 END) OVER (PARTITION BY P.ID, P.BC, P.PCD, P.CID, P.BRC) ST_F
, SUM(CASE WHEN P.ST = 'N' THEN 1 ELSE 0 END) OVER (PARTITION BY P.ID, P.BC, P.PCD, P.COMP_CODE, P.BRC) ST_N
, SUM(CASE WHEN P.ST = 'A' THEN 1 ELSE 0 END) OVER (PARTITION BY P.ID, P.BC, P.PCD, P.CID, P.BRC) ST_A
FROM
EED_TABLE P
WHERE
P.CD = 1
AND P.ID = 1
AND P.BC = 22
AND P.PCD = 31
AND EXISTS (SELECT 1 FROM EDD_DEF D WHERE P.PCD = D.PCD AND P.BC= D.BC)
I have the following code.
It has 2 dates:
1.
(case
when not trunc(iv.dated) is null then trunc(iv.dated) else trunc(iv1.dated)
end) date_stock_received
2.
trunc(dh.actshpdate) SHIP_DATE
Is there a way to join the dates so they show in one column?
select unique li.catnr, li.av_part_no,
(select sum(pl.qty_onhand) from part_loc pl where li.av_part_no = pl.part_no) qty_onhand,
(case
when not trunc(iv.dated) is null then trunc(iv.dated) else trunc(iv1.dated)
end) date_stock_received,
(case
when not sum(iv.quantity) is null then sum(iv.quantity) else sum(iv1.quantity)
end) qty_received,
dp.delqty, od.ord_extordnr, trunc(dh.actshpdate) SHIP_DATE
from leos_item li
LEFT JOIN scm_packtyp sp
ON li.packtyp = sp.packtyp
LEFT JOIN invtran_view_oes iv
ON li.av_part_no = iv.part_no
and (iv.transaction = 'NREC' and iv.location_no = ' RETURNS W')
LEFT JOIN invtran_view_oes iv1
on li.av_part_no = iv1.part_no
and (iv1.transaction = 'CORR+' and iv1.remark like 'STOCK FROM SP PALLET%')
LEFT JOIN oes_delsegview od
ON od.catnr = li.catnr
and od.prodtyp = li.prodtyp
and od.packtyp = li.packtyp
LEFT JOIN oes_dpos dp
ON od.ordnr = dp.ordnr
and od.posnr = dp.posnr
and od.segnr = dp.segnr
LEFT JOIN oes_dhead dh
on dp.dheadnr = dh.dheadnr
and dh.shpfromloc = 'W'
where li.cunr = '816900'
and substr(li.catnr,1,5) in ('RGMCD','RGJCD')
and li.item_type = 'FP'
and li.catnr = 'RGJCD221'
group by li.catnr, li.av_part_no, iv.dated, iv.quantity, iv1.dated, iv1.quantity, dp.delqty,
dp.ordnr, dp.posnr, dp.segnr, od.ord_extordnr, dh.actshpdate
order by li.av_part_no
Current result is ...
... what I would like to see is ...
Is this possible ?
The coalesce function might be what you want.
select trunc(coalesce(iv.dated, iv1.dated, dh.actshpdate)) theDateYouMightWant
I am receiving this error when trying to execute the query below. Any ideas or suggestions?
Error:
Multiple columns are specified in an aggregated expression containing an outer reference. If an expression being aggregated contains an outer reference, then that outer reference must be the only column referenced in the expression.
SELECT TestInstances.pkTestInstanceID AS 'pkTestInstanceID',
bands.pkPerformanceLevelReportBandID AS 'BandID',
bands.StackPosition AS 'StackPosition',
(SELECT TOP 100 PERCENT SUM(CASE WHEN bands.StackPosition = b.StackPosition THEN 1 ELSE 0 END) * 100/ CASE WHEN COUNT(StudentScores_Subject.pkStudentScoreID) = 0 THEN 1 ELSE COUNT(StudentScores_Subject.pkStudentScoreID) END
FROM PerformanceLevelReportBands b
WHERE b.fkPerformanceLevelReportID = #intPerfLevelReportId
ORDER BY SUM(CASE WHEN bands.StackPosition = b.StackPosition THEN 1 ELSE 0 END) * 100/ CASE WHEN COUNT(StudentScores_Subject.pkStudentScoreID) = 0 THEN 1 ELSE COUNT(StudentScores_Subject.pkStudentScoreID) END) AS 'Percent',
COUNT(StudentScores_Subject.pkStudentScoreID) AS 'Count'
FROM StudentScores_Subject
INNER JOIN StudentTests ON StudentScores_Subject.fkStudentTestID = StudentTests.pkStudentTestID
INNER JOIN TestInstances ON TestInstances.pkTestInstanceID = StudentTests.fkTestInstanceID
INNER JOIN CAHSEE_TestPeriods ON CAHSEE_TestPeriods.pkTestPeriodID = TestInstances.fkTestPeriodID
INNER JOIN PerformanceLevelReportBands bands ON bands.fkPerformanceLevelReportID = #intPerfLevelReportId
LEFT JOIN MMARS_Web_TestInfo_California.dbo.PerfLevelReportBandCutScores cutScores ON cutScores.fkPerformanceLevelReportBandID = bands.pkPerformanceLevelReportBandID
AND cutScores.fkGradeID = #intGradeId
AND cutScores.fkTestSubjectID IN (SELECT id FROM #tempSubs)
INNER JOIN PerfLevelReportBandComponents bandComponents ON bandComponents.fkPerformanceLevelReportBandID = bands.pkPerformanceLevelReportBandID
AND((bandComponents.ScoreValue = StudentScores_Subject.ScoreValue) OR
((CAST(StudentScores_Subject.ScoreValue AS INT) BETWEEN bandComponents.minScore and bandComponents.maxScore)
OR
(CAST(StudentScores_Subject.ScoreValue AS INT) BETWEEN cutScores.minScore and cutScores.maxScore)))
RIGHT JOIN MM_SchoolYears ON MM_SchoolYears.pkSchoolYearID = TestInstances.fkSchoolYearID
WHERE MM_SchoolYears.pkSchoolYearID IN (SELECT number FROM itot(#strYearIds, N','))
AND StudentScores_Subject.fkStudentTestID IN (SELECT id FROM #tempTests)
AND StudentScores_Subject.fkScoreTypeID = bandComponents.fkScoreTypeID
AND StudentScores_Subject.fkTest_SubjectID IN (SELECT id FROM #tempSubs)
GROUP BY TestInstances.pkTestInstanceID, bands.pkPerformanceLevelReportBandID, bands.StackPosition
ORDER BY TestInstances.pkTestInstanceID, bands.pkPerformanceLevelReportBandID, bands.StackPosition
The problem is here you can't combine an outer and inner reference in an aggregate function
(SELECT TOP 100 PERCENT SUM(CASE WHEN bands.StackPosition = b.StackPosition THEN 1 ELSE 0 END) * 100/ CASE
WHEN COUNT(StudentScores_Subject.pkStudentScoreID) = 0 THEN 1
ELSE COUNT(StudentScores_Subject.pkStudentScoreID)
END
FROM PerformanceLevelReportBands b
WHERE b.fkPerformanceLevelReportID = #intPerfLevelReportId
ORDER BY SUM(CASE WHEN bands.StackPosition = b.StackPosition THEN 1 ELSE 0 END) * 100/ CASE
WHEN COUNT(StudentScores_Subject.pkStudentScoreID) = 0 THEN 1
ELSE COUNT(StudentScores_Subject.pkStudentScoreID)
END) AS 'Percent'
So change it to
(SELECT TOP 100 PERCENT SUM(CASE WHEN bb.StackPosition = b.StackPosition THEN 1 ELSE 0 END) * 100/ CASE
WHEN COUNT(StudentScores_Subject.pkStudentScoreID) = 0 THEN 1
ELSE COUNT(StudentScores_Subject.pkStudentScoreID)
END
FROM PerformanceLevelReportBands b JOIN PerformanceLevelReportBands bb
ON bb.fkPerformanceLevelReportID =bands.fkPerformanceLevelReportID
AND b.fkPerformanceLevelReportID =bb.fkPerformanceLevelReportID
WHERE b.fkPerformanceLevelReportID = #intPerfLevelReportId
ORDER BY SUM(CASE WHEN bb.StackPosition = b.StackPosition THEN 1 ELSE 0 END) * 100/ CASE
WHEN COUNT(StudentScores_Subject.pkStudentScoreID) = 0 THEN 1
ELSE COUNT(StudentScores_Subject.pkStudentScoreID)
END) AS 'Percent'
Here is a more thorough explanation.
I'd recommend commenting out bandComponents then cutScores, rerunning after removing each components and seeing where the query fails. Once you figure out where it's failing, then you can fix it.
Also, could be this line, the query in your Percent column.
ORDER BY SUM(CASE WHEN bands.StackPosition = b.StackPosition THEN 1 ELSE 0 END) * 100
I tried to organize your query a bit better to make it more legible.
SELECT
TestInstances.pkTestInstanceID AS 'pkTestInstanceID'
, bands.pkPerformanceLevelReportBandID AS 'BandID'
, bands.StackPosition AS 'StackPosition'
, (
SELECT TOP 100 PERCENT
SUM( CASE
WHEN bands.StackPosition = b.StackPosition
THEN 1
ELSE 0
END) * 100 /
CASE
WHEN COUNT(StudentScores_Subject.pkStudentScoreID) = 0
THEN 1
ELSE COUNT(StudentScores_Subject.pkStudentScoreID)
END
FROM PerformanceLevelReportBands b
WHERE b.fkPerformanceLevelReportID = #intPerfLevelReportId
ORDER BY SUM(CASE WHEN bands.StackPosition = b.StackPosition THEN 1 ELSE 0 END) * 100
/
CASE
WHEN COUNT(StudentScores_Subject.pkStudentScoreID) = 0
THEN 1
ELSE COUNT(StudentScores_Subject.pkStudentScoreID)
END
) AS 'Percent'
, COUNT(StudentScores_Subject.pkStudentScoreID) AS 'Count'
FROM
StudentScores_Subject
INNER JOIN
StudentTests ON
StudentScores_Subject.fkStudentTestID = StudentTests.pkStudentTestID
INNER JOIN
TestInstances ON
TestInstances.pkTestInstanceID = StudentTests.fkTestInstanceID
INNER JOIN
CAHSEE_TestPeriods ON
CAHSEE_TestPeriods.pkTestPeriodID = TestInstances.fkTestPeriodID
INNER JOIN
PerformanceLevelReportBands bands ON
bands.fkPerformanceLevelReportID = #intPerfLevelReportId
LEFT JOIN
MMARS_Web_TestInfo_California.dbo.PerfLevelReportBandCutScores cutScores ON
cutScores.fkPerformanceLevelReportBandID = bands.pkPerformanceLevelReportBandID
AND cutScores.fkGradeID = #intGradeId
AND cutScores.fkTestSubjectID IN (SELECT id FROM #tempSubs)
INNER JOIN
PerfLevelReportBandComponents bandComponents ON
bandComponents.fkPerformanceLevelReportBandID = bands.pkPerformanceLevelReportBandID
AND(
(bandComponents.ScoreValue = StudentScores_Subject.ScoreValue) OR
(
(CAST(StudentScores_Subject.ScoreValue AS INT) BETWEEN bandComponents.minScore and bandComponents.maxScore) OR
(CAST(StudentScores_Subject.ScoreValue AS INT) BETWEEN cutScores.minScore and cutScores.maxScore)
)
)
RIGHT JOIN
MM_SchoolYears ON
MM_SchoolYears.pkSchoolYearID = TestInstances.fkSchoolYearID
WHERE
MM_SchoolYears.pkSchoolYearID IN (SELECT number FROM itot(#strYearIds, N','))
AND StudentScores_Subject.fkStudentTestID IN (SELECT id FROM #tempTests)
AND StudentScores_Subject.fkScoreTypeID = bandComponents.fkScoreTypeID
AND StudentScores_Subject.fkTest_SubjectID IN (SELECT id FROM #tempSubs)
GROUP BY TestInstances.pkTestInstanceID, bands.pkPerformanceLevelReportBandID, bands.StackPosition
ORDER BY TestInstances.pkTestInstanceID, bands.pkPerformanceLevelReportBandID, bands.StackPosition
I faced the same problem or something similar.
I left here both the initial code and the resolution in case it helps you.
Initial code:
SELECT ISNULL((SELECT DateName(mm,DATEADD(mm,Perioada - 1,0))),'Nedefinit') as [Period],MAX(t.TipPerioada) AS TipPerioada,t.Perioada,MAX(t.An) AS An, a.NumePrenume, CAST(t.Volum as float) as ValTip,
ISNULL((Select Sum(v.Cantitate*p.VolumProdus)
From Wme_Vanzari as v
WHERE ('ND'='ND' or v.MarcaAgent = t.MarcaAgent) and t.[An]=v.AnFactura and t.Perioada=v.Lunafactura),0) as Realizat,
'' as Diferenta,'' as DiferentaWD,'' as Procent
FROM [Memo_Target] t
--Aduce Suma de Cantitate si MarcaAgent pentru a nu dubla cu liniile din Vanzari
LEFT JOIN (Select SUM(Cantitate) as Cantitate, MarcaAgent
From Wme_Vanzari
WHERE AnFactura = #An
GROUP BY MarcaAgent) v on t.MarcaAgent = v.MarcaAgent
LEFT JOIN WME_Agenti a on a.Marca = t.MarcaAgent
--Aduce Suma de VolumProdus, CodProdus si Marca Agent Filtrat dupa Anul dat in parametru, Volum necesar pt a calcula Realizat si a scade din targetul setat
LEFT JOIN (SELECT SUM(ISNULL(n.VolumProdus, 0)) AS VolumProdus, v.CodProdus, v.MarcaAgent
FROM Wme_NomenclatorProduse n
LEFT JOIN Wme_Vanzari v ON v.CodProdus = n.CodIntern
WHERE v.MarcaAgent IS NOT NULL AND v.CodProdus IS NOT NULL AND v.AnFactura = #An
GROUP BY v.CodProdus, v.MarcaAgent ) p ON p.MarcaAgent = t.MarcaAgent
WHERE (t.Volum IS NOT NULL AND t.Volum > 0)
AND t.An = #An
AND (CAST(t.Perioada AS INT) BETWEEN #lunastart AND #lunaend)
AND TipTarget = #tiptarget
AND (a.Marca IN (SELECT * FROM dbo.GetIdsTableString(#marcaAgent)) OR #marcaAgent = 'ND')
GROUP BY a.NumePrenume, t.Volum, Perioada,t.An
Error message was the same, and this is the resolution code:
SELECT ISNULL((SELECT DateName(mm,DATEADD(mm,Perioada - 1,0))),'Nedefinit') as [Period],MAX(t.TipPerioada) AS TipPerioada,t.Perioada,MAX(t.An) AS An, a.NumePrenume, CAST(t.Volum as float) as ValTip,
(ISNULL((Select Sum(p.VolumProdus)
From Wme_Vanzari as v
WHERE ('ND'='ND' or v.MarcaAgent = t.MarcaAgent) and t.[An]=v.AnFactura and t.Perioada=v.Lunafactura),0) * sum(v.Cantitate)) as Realizat,
'' as Diferenta,'' as DiferentaWD,'' as Procent
FROM [Memo_Target] t
--Aduce Suma de Cantitate si MarcaAgent pentru a nu dubla cu liniile din Vanzari
LEFT JOIN (Select SUM(Cantitate) as Cantitate, MarcaAgent
From Wme_Vanzari
WHERE AnFactura = #An
GROUP BY MarcaAgent) v on t.MarcaAgent = v.MarcaAgent
LEFT JOIN WME_Agenti a on a.Marca = t.MarcaAgent
--Aduce Suma de VolumProdus, CodProdus si Marca Agent Filtrat dupa Anul dat in parametru, Volum necesar pt a calcula Realizat si a scade din targetul setat
LEFT JOIN (SELECT SUM(ISNULL(n.VolumProdus, 0)) AS VolumProdus, v.CodProdus, v.MarcaAgent
FROM Wme_NomenclatorProduse n
LEFT JOIN Wme_Vanzari v ON v.CodProdus = n.CodIntern
WHERE v.MarcaAgent IS NOT NULL AND v.CodProdus IS NOT NULL AND v.AnFactura = #An
GROUP BY v.CodProdus, v.MarcaAgent ) p ON p.MarcaAgent = t.MarcaAgent
WHERE (t.Volum IS NOT NULL AND t.Volum > 0)
AND t.An = #An
AND (CAST(t.Perioada AS INT) BETWEEN #lunastart AND #lunaend)
AND TipTarget = #tiptarget
AND (a.Marca IN (SELECT * FROM dbo.GetIdsTableString(#marcaAgent)) OR #marcaAgent = 'ND')
GROUP BY a.NumePrenume, t.Volum, Perioada,t.An
As you can see, I chose to leave a single column in the first subselect and i was forced to use multiplication operation after this subselect.
I hope it helps!
I have a stored procedure where I have to join a table only on rows where a bit field for that record is 0. Is this possible? Here's what I have/need
SELECT TOP 100
SR.ServiceRecordID,
dbo.fn_ServiceRecordGetServiceName(SR.ServiceRecordID,''),
SR.LocationStd,
SR.AreaServedStd,
SR.RegionalLimited,
R.Region,
CASE WHEN (ISNULL(R_SR.RegionID,0) = 0 AND ISNULL(R_SR_Serv.RegionID,0) = 0)
THEN 0 ELSE 1 END AS Visible,
NULL
FROM ServiceRecord SR
INNER JOIN Sites S
ON SR.SiteID = S.SiteID
INNER JOIN Regions R
ON R.SiteID = S.SiteID
LEFT OUTER JOIN lkup_Region_ServiceRecord R_SR
ON R_SR.RegionID = R.RegionID
AND R_SR.ServiceRecordID = SR.ServiceRecordID
--and this is the additional join I need ONLY if RegionalLimited = 0
CASE WHEN SR.RegionalLimited = 0 THEN
LEFT OUTER JOIN lkup_Region_ServiceRecord_Serv R_SR_Serv
ON R_SR_Serv.RegionID = R.RegionID
AND R_SR_Serv.ServiceRecordID = SR.ServiceRecordID
END
WHERE SR.SiteID = #SiteID
AND R.RegionID % 100 != 0
This should work
SELECT TOP 100 SR.ServiceRecordID, dbo.fn_ServiceRecordGetServiceName(SR.ServiceRecordID,''),
SR.LocationStd, SR.AreaServedStd,
SR.RegionalLimited, R.Region,
CASE WHEN (ISNULL(R_SR.RegionID,0) = 0 AND ISNULL(R_SR_Serv.RegionID,0) = 0) THEN 0 ELSE 1 END AS Visible,NULL
FROM ServiceRecord SR
INNER JOIN Sites S ON SR.SiteID = S.SiteID
INNER JOIN Regions R ON R.SiteID = S.SiteID
LEFT OUTER JOIN lkup_Region_ServiceRecord R_SR ON R_SR.RegionID = R.RegionID
AND R_SR.ServiceRecordID = SR.ServiceRecordID
LEFT OUTER JOIN lkup_Region_ServiceRecord_Serv R_SR_Serv
ON R_SR_Serv.RegionID = R.RegionID
AND R_SR_Serv.ServiceRecordID = SR.ServiceRecordID
AND SR.RegionalLimited = 0 -- this is the trick
WHERE SR.SiteID = #SiteID
AND R.RegionID % 100 != 0
I have added this condition AND SR.RegionalLimited = 0 to the left outer join with lkup_Region_ServiceRecord