I am trying to compile a subquery in MSSQL 2012 to extract container volumes in import shipments using the following
SELECT TOP (100) PERCENT JobShipment_1.JS_UniqueConsignRef, JobContainer_1.JC_ContainerNum,
(SELECT dbo.JobPackLines.JL_ActualVolume
FROM dbo.JobPackLines INNER JOIN
dbo.JobShipment ON dbo.JobPackLines.JL_JS = dbo.JobShipment.JS_PK INNER JOIN
dbo.JobContainerPackPivot ON dbo.JobPackLines.JL_PK = dbo.JobContainerPackPivot.J6_JL INNER JOIN
dbo.JobContainer ON dbo.JobContainerPackPivot.J6_JC = dbo.JobContainer.JC_PK) AS Expr1
FROM dbo.JobConsol INNER JOIN
dbo.JobConShipLink ON dbo.JobConsol.JK_PK = dbo.JobConShipLink.JN_JK INNER JOIN
dbo.JobShipment AS JobShipment_1 ON dbo.JobConShipLink.JN_JS = JobShipment_1.JS_PK INNER JOIN
dbo.cvw_JobShipmentOrgs ON JobShipment_1.JS_PK = dbo.cvw_JobShipmentOrgs.JS_PK INNER JOIN
dbo.JobContainer AS JobContainer_1 ON dbo.JobConsol.JK_PK = JobContainer_1.JC_JK INNER JOIN
dbo.JobDeclaration ON JobShipment_1.JS_PK = dbo.JobDeclaration.JE_JS
But get the following error
"Error Message: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <=, >, >= or when the subquery is used as an expression."
I have looked ad nauseum on the web, but cannot find an answer, can anyone help?
Many thanks
Try this query
SELECT TOP (100) PERCENT JobShipment_1.JS_UniqueConsignRef, JobContainer_1.JC_ContainerNum,
(SELECT a.JL_ActualVolume
FROM dbo.JobPackLines a
INNER JOIN dbo.JobShipment b ONa.JL_JS = b.JS_PK
INNER JOIN dbo.JobContainerPackPivot c ON a.JL_PK = c.J6_JL
INNER JOIN dbo.JobContainer d ON c.J6_JC = d.JC_PK
where b.JS_PK=JobShipment_1.JS_PDK and d.JC_PK=JobContainer_1.JC_PK
) AS Expr1
FROM dbo.JobConsol
INNER JOIN dbo.JobConShipLink ON dbo.JobConsol.JK_PK = dbo.JobConShipLink.JN_JK
INNER JOIN dbo.JobShipment AS JobShipment_1 ON dbo.JobConShipLink.JN_JS = JobShipment_1.JS_PK
INNER JOIN dbo.cvw_JobShipmentOrgs ON JobShipment_1.JS_PK = dbo.cvw_JobShipmentOrgs.JS_PK
INNER JOIN dbo.JobContainer AS JobContainer_1 ON dbo.JobConsol.JK_PK = JobContainer_1.JC_JK
INNER JOIN dbo.JobDeclaration ON JobShipment_1.JS_PK = dbo.JobDeclaration.JE_JS
Please try below:
SELECT TOP (100) PERCENT JobShipment_1.JS_UniqueConsignRef, JobContainer_1.JC_ContainerNum,
(SELECT JPL.JL_ActualVolume
FROM dbo.JobPackLines AS JPL
INNER JOIN dbo.JobShipment AS JS ON JS.JS_PK = JPL.JL_JS
INNER JOIN dbo.JobContainerPackPivot AS JCP ON JCP.J6_JL = JPL.JL_PK
INNER JOIN dbo.JobContainer AS JC ON JC.JC_PK = JPL.J6_JC) AS Expr1
FROM dbo.JobConsol
INNER JOIN dbo.JobConShipLink ON dbo.JobConsol.JK_PK = dbo.JobConShipLink.JN_JK
INNER JOIN dbo.JobShipment AS JobShipment_1 ON dbo.JobConShipLink.JN_JS = JobShipment_1.JS_PK
INNER JOIN dbo.cvw_JobShipmentOrgs ON JobShipment_1.JS_PK = dbo.cvw_JobShipmentOrgs.JS_PK
INNER JOIN dbo.JobContainer AS JobContainer_1 ON dbo.JobConsol.JK_PK = JobContainer_1.JC_JK
INNER JOIN dbo.JobDeclaration ON JobShipment_1.JS_PK = dbo.JobDeclaration.JE_JS
Related
I have a SQL query that I'm trying to optimize.
Is there a better way to avoid using subquery here?
Got a suggestion on using Row_number(),
posting this with some corrections
DECLARE #curdate DATETIME
SET #curdate = GETDATE()
SELECT DISTINCT
SIS.StudentID, StudentCoverage.StudentCoverageDataID,
Student.FirstName, Student.LastName,
Student.DateOfBirth, Student.Gender,
ASMT.AssessmentDate
FROM
SIS (NOLOCK)
INNER JOIN
SISMaster (NOLOCK) ON SISMaster.SISID = SIS.SISID
INNER JOIN
Assessment ASMT ON SIS.StudentID = ASMT.StudentId
INNER JOIN
StudentCoverage (NOLOCK) ON StudentCoverage.StudentID = SIS.StudentID
INNER JOIN
Organization (NOLOCK) ON StudentCoverage.OrgID = Organization.OrganizationID
INNER JOIN
Student (NOLOCK) ON Student.StudentID = SIS.StudentID
INNER JOIN
StudentCoverageData (NOLOCK) ON StudentCoverageData.StudentCoverageID = StudentCoverage.StudentCoverageID
AND StudentCoverageData.StudentCoverageDataID = (SELECT TOP 1 StudentCoverageData.StudentCoverageDataID
FROM StudentCoverage
INNER JOIN StudentCoverageData ON StudentCoverageData.StudentCoverageID = StudentCoverage.StudentCoverageID
WHERE StudentCoverage.StudentId = SIS.StudentID
AND StudentCoverageData.Active = 1
AND StudentCoverageData.EffectiveDate <= #curdate
AND (StudentCoverageData.ExitDate IS NULL OR StudentCoverageData.ExitDate > #curdate)
ORDER BY StudentCoverageData.AsOfDate DESC)
All Tables in your subquery is exists in inner join clause, so you could rewrite your query like this:
;WITH temps AS
(
DECLARE #curdate DATETIME = GETDATE()
SELECT
SIS.StudentID, StudentCoverage.StudentCoverageDataID,
Student.FirstName, Student.LastName,
Student.DateOfBirth, Student.Gender,
ASMT.AssessmentDate,
ROW_NUMBER() OVER (PARTITION BY StudentCoverageData.StudentCoverageDataID ORDER BY StudentCoverageData.AsOfDate) AS RowIndex
FROM
SIS (NOLOCK)
INNER JOIN
SISMaster (NOLOCK) ON SISMaster.SISID = SIS.SISID
INNER JOIN
StudentCoverage (NOLOCK) ON StudentCoverage.StudentID = SIS.StudentID
INNER JOIN
Organization (NOLOCK) ON StudentCoverage.OrgID = Organization.OrganizationID
INNER JOIN
Student (NOLOCK) ON Student.StudentID = SIS.StudentID
INNER JOIN
StudentCoverageData (NOLOCK) ON StudentCoverageData.StudentCoverageID = StudentCoverage.StudentCoverageID
WHERE StudentCoverageData.Active = 1
AND StudentCoverageData.EffectiveDate <= #curdate
AND (StudentCoverageData.ExitDate IS NULL OR StudentCoverageData.ExitDate > #curdate)
)
SELECT * FROM temps t
WHERE t.RowIndex = 1
I had written a join query statement. that statement returns me multiple(duplicate) row again even though I'm having only single record on that.
declare #BenefitClass int ;
set #BenefitClass = (select BenefitClass From HJOB where userid='d76c5000-69e0-461e-92e1-3cfe7590d098' and CompanyId =1629)
select #BenefitClass;
select
bve.EmployerContribution,
bhsac.CatchUpValue as CatchUpValue ,
bcl.Tier,
bcl.planYear,
bhsac.Ischecked,
isnull(bhsac.Value,0) as EmployeeContribute,
Id=(convert(varchar, bcl.Id) + '$' + convert(varchar, isnull(bhsac.Id, 0))) ,
bhsac.Value ,
bhsac.HSALmitId
from
dbo.benContributionStructure bcs
inner join dbo.benVariableElection bve on bcs.PlanInfoId = bve.PlanInfoId
inner join dbo.benBenefitContributionLimit bcl on bcs.SavingCategory = bcl.CategoryID
left outer join dbo.benBenefitHSACoverage bhsac on bcs.PlanInfoId = bhsac.planInfoId
and bcl.Id=bhsac.HSALmitId --and bhsac.BenefitClassId=#BenefitClass
and bhsac.UserID='d76c5000-69e0-461e-92e1-3cfe7590d098' and bhsac.PlanInfoId=38044
left outer join dbo.benEmployeeContribution bec on bhsac.UserID = bec.UserId and bhsac.BenefitClassId = bec.BenefitClassId -- and bec.EnrollmentType !='Closed'
left outer join benOpenEnrollment oems on oems.ID = bec.OpenEnrollmentId and oems.EndDt > GETDATE()
where
bcs.PlanInfoId=38044 and bcl.Ischecked=1
and bcl.Tier !='CatchUp'
and bcl.CompanyId=1629
For that I'm getting the result as second row as duplicate :
observe the result
Try this once it may help you
declare #BenefitClass int ;
set #BenefitClass = (select BenefitClass From HJOB where userid='d76c5000-69e0-461e-92e1-3cfe7590d098' and CompanyId =1629)
select #BenefitClass;
;with cte as (
select
bve.EmployerContribution,
bhsac.CatchUpValue as CatchUpValue ,
bcl.Tier,
bcl.planYear,
bhsac.Ischecked,
isnull(bhsac.Value,0) as EmployeeContribute,
Id=(convert(varchar, bcl.Id) + '$' + convert(varchar, isnull(bhsac.Id, 0))) ,
bhsac.Value ,
bhsac.HSALmitId
from
dbo.benContributionStructure bcs
inner join dbo.benVariableElection bve on bcs.PlanInfoId = bve.PlanInfoId
inner join dbo.benBenefitContributionLimit bcl on bcs.SavingCategory = bcl.CategoryID
left outer join dbo.benBenefitHSACoverage bhsac on bcs.PlanInfoId = bhsac.planInfoId
and bcl.Id=bhsac.HSALmitId --and bhsac.BenefitClassId=#BenefitClass
and bhsac.UserID='d76c5000-69e0-461e-92e1-3cfe7590d098' and bhsac.PlanInfoId=38044
left outer join dbo.benEmployeeContribution bec on bhsac.UserID = bec.UserId and bhsac.BenefitClassId = bec.BenefitClassId -- and bec.EnrollmentType !='Closed'
left outer join benOpenEnrollment oems on oems.ID = bec.OpenEnrollmentId and oems.EndDt > GETDATE()
where
bcs.PlanInfoId=38044 and bcl.Ischecked=1
and bcl.Tier !='CatchUp'
and bcl.CompanyId=1629
)
select distinct EmployerContribution,
CatchUpValue ,Tier,planYear,Ischecked,EmployeeContribute,Id ,Value ,HSALmitId from cte
Please change your where condition as below:
select
bve.EmployerContribution,
bhsac.CatchUpValue as CatchUpValue ,
bcl.Tier,
bcl.planYear,
bhsac.Ischecked,
isnull(bhsac.Value,0) as EmployeeContribute,
Id=(convert(varchar, bcl.Id) + '$' + convert(varchar, isnull(bhsac.Id, 0))) ,
bhsac.Value ,
bhsac.HSALmitId
from
dbo.benContributionStructure bcs
inner join dbo.benVariableElection bve on bcs.PlanInfoId = bve.PlanInfoId
inner join dbo.benBenefitContributionLimit bcl on bcs.SavingCategory = bcl.CategoryID
left outer join dbo.benBenefitHSACoverage bhsac on bcs.PlanInfoId = bhsac.planInfoId
and bcl.Id=bhsac.HSALmitId --and bhsac.BenefitClassId=#BenefitClass
left outer join dbo.benEmployeeContribution bec on bhsac.UserID = bec.UserId and bhsac.BenefitClassId = bec.BenefitClassId -- and bec.EnrollmentType !='Closed'
left outer join benOpenEnrollment oems on oems.ID = bec.OpenEnrollmentId
where
bcs.PlanInfoId=38044 and bcl.Ischecked=1
and bcl.Tier !='CatchUp'
and bcl.CompanyId=1629
and bhsac.UserID='d76c5000-69e0-461e-92e1-3cfe7590d098'
and bhsac.PlanInfoId=38044
and oems.EndDt > GETDATE()
How to change this query to use joins (inner or left) but not subquery
SELECT * FROM External_Blk_Itm_Contracts ELC
WHERE
NOT EXISTS(SELECT
NULL
FROM
[BUDCONTRACTS] c
INNER JOIN
BUDTERMINALS t on t.TerminalID = c.TerminalID AND t.MBFTERMINALNAME = ELC.TerminalName AND c.CONTRACTNAME = ELC.ContractName
INNER JOIN
BudCustomers ct on ct.CustomerId = c.CustomerId AND ELC.CustomerName = ct.LegalName
)
AND ELC.ContractName = '00-000'
Untested (obviously):
SELECT distinct
ELC.*
FROM
External_Blk_Itm_Contracts ELC
LEFT JOIN
BUDCONTRACTS c on c.CONTRACTNAME = ELC.ContractName
LEFT JOIN
BUDTERMINALS t on t.TerminalID = c.TerminalID and t.MBFTERMINALNAME = ELC.TerminalName
LEFT JOIN
BudCustomers ct on ct.CustomerId = c.CustomerId and ELC.CustomerName = ct.LegalName
WHERE
c.CONTRACTNAME is NULL
and t.TerminalID is NULL
and ct.CustomerID is NULL
AND ELC.ContractName = '00-000'
My biggest question about this is why we're joining using name fields to ELC? Isn't there e.g. TerminalID, CustomerID and CotractID available on ELC?
I fixed this by
SELECT ELC.* FROM External_Blk_Itm_Contracts ELC
INNER JOIN BUDTERMINALS BT ON BT.MBFTERMINALNAME = ELC.TerminalName AND ELC.ContractName = '00-000'
INNER JOIN BudCustomers BCUST ON BCUST.LegalName = ELC.CustomerName
LEFT JOIN BUDCONTRACTS BCON ON BCON.CONTRACTNAME = ELC.ContractName AND BCON.TERMINALID = BT.TERMINALID AND BCON.CUSTOMERID = BCUST.CustomerID
WHERE BCON.CONTRACTID IS NULL
The following is my CTE:
;WITH CTE AS
(SELECT O.*, E.Num, E.Amount
FROM OData O
INNER JOIN Equip E
ON O.Name = E.Name)
SELECT * FROM CTE -- gives results I want to join to
The following is the query that I want to SELECT from (and only use this SELECT statement for my query results:
SELECT
MU.Type
,MU.Num
,MU.MTBUR
,MF.MTBF
,MU.Hours
,MF.Hours
FROM
MUType_Stage MU
INNER JOIN
MFType_Stage MF
ON
MU.Type = MF.Type
AND
MU.Num = MF.Num
-- Need do JOIN to CTE right here
INNER JOIN
Status_STAGE S
ON
MU.Nu = S.Part
LEFT OUTER JOIN
RCN N
ON
N.Name = R.Part
LEFT OUTER JOIN
Repair RR
ON
R.ACSS_Name = RR.Name
So basically I need to JOIN to the CTE inside the SELECT query in which I want the results.
OR ALTERNATIVELY Uses this select statement to join to the CTE but only what the selected columns from the second select statement
Try this syntax
WITH CTE
AS (SELECT O.*,
E.Num,
E.Amount
FROM OData O
INNER JOIN Equip E
ON O.Name = E.Name)
SELECT MU.Type,
MU.Num,
MU.MTBUR,
MF.MTBF,
MU.Hours,
MF.Hours
FROM MUType_Stage MU
INNER JOIN MFByACType_Stage MF
ON MU.Type = MF.Type
AND MU.Num = MF.Num
INNER JOIN CTE C --- JOIN HERE as like other tables
ON C.Num = MF.Num
INNER JOIN Status_STAGE S
ON MU.Nu = S.Part
LEFT OUTER JOIN RCN N
ON N.Name = R.Part
LEFT OUTER JOIN Repair RR
ON R.ACSS_Name = RR.Name
I added Project_Contract.ContractorName but query got error.
Msg 156, Level 15, State 1, Line 18 Incorrect syntax near the keyword 'GROUP'.
select top (100) percent dbo.Project_Profile.Project_ID
,dbo.Project_Contract.ContractorName
,dbo.Schemes.Scheme_Name as [Name of Project]
,dbo.Program_Ctrl.Program_Title as [Contract Status]
,dbo.District_Ctrl.District_Name as District
,M.Module_Title as Module
,(
select MAX(Progress_Percentage) as Expr1
from dbo.Progress_Reporting as PR
where (M.ModuleID = Module_Id)
and (dbo.Milestone_Ctrl.Milestone_ID = Project_Milestone_ID)
and (Progress_Type = 'A')
) as Milestone_Percent_Share
,dbo.Milestone_Ctrl.Milestone_Title
from dbo.District_Ctrl
inner join dbo.Project_Profile
inner join dbo.Project_Profile
inner join dbo.Project_Contract
on dbo.Project_Profile.Project_ID = dbo.Project_Contract.ProjectId
inner join dbo.Schemes
on dbo.Project_Profile.Scheme_id = dbo.Schemes.Scheme_id
inner join dbo.Program_Ctrl
on dbo.Project_Profile.Program_ID = dbo.Program_Ctrl.Program_ID
inner join dbo.Project_Modules
on dbo.Project_Profile.Project_ID = dbo.Project_Modules.ProjectId
on dbo.District_Ctrl.District_ID = dbo.Schemes.District_ID inner join dbo.Modules_Ctrl as M
on M.ModuleID = dbo.Project_Modules.ModuleID
inner join dbo.Milestone_Ctrl
inner join dbo.Project_Milestones
on dbo.Milestone_Ctrl.Milestone_ID = dbo.Project_Milestones.Project_Milestone_ID
on M.ModuleID = dbo.Project_Milestones.ModuleId
group by dbo.Project_Profile.Project_ID
,dbo.Project_Contract.ContractorName
,dbo.Schemes.Scheme_Name
,dbo.Program_Ctrl.Program_Title
,M.Module_Title
,dbo.Project_Modules.ProjectModuleId
,dbo.Project_Milestones.Project_Milestone_ID
,dbo.District_Ctrl.District_Name
,dbo.Project_Milestones.Milestone_Percent_Share
,dbo.Project_Milestones.MileStoneId
,dbo.Milestone_Ctrl.Milestone_ID
,dbo.Milestone_Ctrl.Milestone_Title
,M.ModuleID
order by dbo.Project_Profile.Project_ID
You have two join with Project_Profile Table and have only one ON for this join you must add another ON for solve your problem or remove dbo.Project_Profile INNER JOIN part command.
Here:
dbo.Project_Profile INNER JOIN
dbo.Project_Profile INNER JOIN
Have duplicate Project_Profile without alias