SQL query very slow and need to be improved - sql

I have a select query that I need to improve to make it fast.
SELECT
st.SigHistUID, st.RelationType, st2.RelationType,
case
when st.RelationType <> st2.RelationType
then 'N'
else st.RelationType
end as [NewRelationType],
st.ToSigUID , sh.FullDescription, sh.SigHistUID AS ToSigHistUID
FROM
[Stackability] (nolock) st
INNER JOIN
[SignatureHistory] (nolock) sh ON sh.SigUID = st.ToSigUID
AND sh.SigHistUID = (SELECT TOP 1 SigHistUID FROM [SignatureHistory] (nolock) tmp where tmp.SigUID = sh.SigUID ORDER BY SigHistUID DESC)
INNER JOIN
[SignatureHistory] (nolock) sh2 ON st.SigHistUID = sh2.SigHistUID
INNER JOIN
Stackability (nolock) st2 on st2.ToSigUID = sh2.SigUID and st2.SigHistUID = sh.SigHistUID
WHERE
st.SigHistUID < 1000 and
st.RelationType <> st2.RelationType
ORDER BY
st.SigHistUID

Try having taken out the top 1 condition:
SELECT
st.SigHistUID, st.RelationType, st2.RelationType,
case
when st.RelationType <> st2.RelationType
then 'N'
else st.RelationType
end as [NewRelationType],
st.ToSigUID , sh.FullDescription, sh.SigHistUID AS ToSigHistUID
FROM
[Stackability] (nolock) st
INNER JOIN
(select distinct siguid, max(SigHistUID) OVER(PARTITION BY siguid ) as SigHistUID from [SignatureHistory] (nolock)) sh ON sh.SigUID = st.ToSigUID
INNER JOIN
[SignatureHistory] (nolock) sh2 ON st.SigHistUID = sh2.SigHistUID
INNER JOIN
Stackability (nolock) st2 on st2.ToSigUID = sh2.SigUID and st2.SigHistUID = sh.SigHistUID
WHERE
st.SigHistUID < 1000 and
st.RelationType <> st2.RelationType
ORDER BY
st.SigHistUID

Related

Else if in my select statement

I want to have an else if in my select statement i have already tried using case when but the results are not so accurate
heres a snippet of my scripts
select distinct t.MovementDate, t.ContractMovementID, t.GID,t.ReferenceGID,
p.refno, t.amount,convert(date,t.CreatedDate) as createdDat
from
LIF_MGM_T_Contract p
inner join LIF_MMS_T_PolicySuspense s with (nolock)
on s.ContractGID = p.GID
inner join LIF_TMS_T_FinancialTransaction t with (nolock)
on t.ContractGID = p.GID
where
p.refno = '1030642 - 1 - Mohahlaula'
and t.ReversedIndicator = 1
and t.counter = (select min(counter)
from LIF_TMS_T_FinancialTransaction t2 with (nolock)
where t2.ContractGID = p.GID
and t2.ReversedIndicator = 1
and t2.MovementDate = t.MovementDate )
So i want a else if t2.reversedindicator = 0 and date = getdate() return results.. Hope this makes sense

Error In My Code : A TOP N or FETCH rowcount value may not be negative

I am getting this error > A TOP N or FETCH rowcount value may not be negative.
I am getting this error in this section of the code. Please Help >>
Select
A2.Employee_Name,
A2.User_Name,
A2.User_Code,
A2.User_Type_Name,
A2.Region_Name,
A2.Region_Code,
A2.Division_Name,
[A3.Day_Count]-[A2.Sunday]-[A2.Holiday] "Total_Days",
IsNull(A4.Reported_Days,0) "Reported_Days",
IsNUll((A5.Non_Reported_Days)-IsNull((A6.Holiday_Count),0),0) "Non_Reported_Days",
Round((Convert(Float,(A4.Reported_Days))/Convert(Float,((A3.Day_Count)-(A2.Sunday)-(A2.Holiday)))*100),0) "Percentage"
From
(
Select
A1.Employee_Name,
A1.User_Name,
A1.User_Code,
A1.User_Type_Name,
A1.Region_Name,
A1.Region_Code,
A1.Division_Name,
Sum(Case When A1.Days = 1 And A1.Holiday = ''0'' Then 1 Else 0 End) "Sunday",
Sum(Case When A1.Holiday <> ''0'' Then 1 Else 0 End) "Holiday"
From
(
Select
E.Employee_Name,
U.User_Code,
U.User_Name,
UT.User_Type_Name,
R.Region_Name,
R.Region_Code,
D.Division_Name,
Datepart(W,D1.Date_Val) "Days",
IsNull(H.Holiday_Name,0)"Holiday"
From
Tbl_Sfa_User_Master U With(Nolock)
Inner Join Tbl_Sfa_Employee_Master E With(Nolock) On (E.Employee_Code = U.Employee_Code)
Inner Join Tbl_Sfa_User_Type_Master UT With(Nolock) On (UT.User_Type_Code = U.User_Type_Code and UT.User_Type_Category <> ''NON_FIELD_USER'')
Inner Join Tbl_Sfa_Region_Master R With(Nolock) On (R.Region_Code = U.Region_Code And R.Region_Status=1)
Inner Join Tbl_Sfa_Division_Entity_Mapping DE With(Nolock) On (DE.Entity_Code = U.User_Code And DE.Entity_Type=''User'')
Inner Join Tbl_Sfa_Division_Master D With(Nolock) On (D.Division_Code = DE.Division_Code And D.Record_Status=1'
If #Division_Name <> ''
Set #Ins_Tbl = #Ins_Tbl + 'And D.Division_Name ='''+#Division_Name+''' '
Set #Ins_Tbl = #Ins_Tbl +')
Inner Join #DW D1 On (1=1)
Left Outer Join Tbl_Sfa_Holiday_Master H With(Nolock) On (H.Region_Code = R.Region_Code and Convert(Date,H.Holiday_Date) = D1.Date_Val And H.Holiday_Status = 0)
Where U.User_Status=1
)A1
Group By
A1.Employee_Name,
A1.User_Code,
A1.User_Name,
A1.User_Type_Name,
A1.Region_Name,
A1.Region_Code,
A1.Division_Name)A2
Left Outer Join
(Select
B.User_Code,
Count(A.Date_Val) "Day_Count"
From
#DW A
Inner Join Tbl_Sfa_User_Master B With(Nolock) On (1=1)
Where B.User_Status=1
Group By B.User_Code) A3 On (A3.User_Code = A2.User_Code)
Left Outer Join
(Select
U.User_Code,
Count(Distinct D.DCR_Code) "Reported_Days"
From
#R_Days A
Inner Join Tbl_sfa_User_Master U With(Nolock) On (1=1)
Inner Join Tbl_Sfa_User_Type_Master UT With(Nolock) On (UT.User_Type_Code = U.User_Type_Code And User_Type_Category <> ''NON_FIELD_USER'')
Inner Join Tbl_Sfa_DCR_Master D With(Nolock) On (D.User_Code = U.User_Code And D.DCR_Actual_Date = A.Date_Val And D.DCR_Status In (''1'',''2''))
Where U.User_Status=1
Group By U.User_Code)A4 On (A4.User_Code = A2.User_Code)
Left Outer Join
(Select
U.User_Code,
Sum(Case When A.Date_Val=D.DCR_Actual_Date Then 0 Else 1 End) "Non_Reported_Days"
From
#R_Days A
Inner Join Tbl_sfa_User_Master U With(Nolock) On (1=1)
Inner Join Tbl_Sfa_User_Type_Master UT With(Nolock) On (UT.User_Type_Code = U.User_Type_Code And User_Type_Category <> ''NON_FIELD_USER'')
Left Outer Join Tbl_Sfa_DCR_Master D With(Nolock) On (D.User_Code = U.User_Code And D.DCR_Actual_Date = A.Date_Val And D.DCR_Status In (''1'',''2''))
Where U.User_Status=1
Group By U.User_Code)A5 On (A5.User_Code = A2.User_Code)
Left Outer Join
(Select
U.User_Code,
Count(H.Holiday_Code) "Holiday_Count"
From
Tbl_Sfa_User_Master U
Inner Join Tbl_Sfa_Region_Master R On (R.Region_Code = U.Region_Code And R.Region_Status=1)
Inner Join Tbl_Sfa_Holiday_Master H On (H.Region_Code = R.Region_Code And H.Holiday_Date Between '''+#Start_Date+''' and '''+#End_Date+''' and H.Holiday_Status=''0'')
Where U.User_Status=1
Group By
U.User_Code)A6 On (A6.User_Code = A5.User_Code)
looks like the issue is here with the syntax,
Set #Ins_Tbl = #Ins_Tbl + 'And D.Division_Name ='''+#Division_Name+''' '
you should have a space between ' and And as,
Set #Ins_Tbl = #Ins_Tbl + ' And D.Division_Name ='''+#Division_Name+''' '
try it if this works

SQl Error : Each GROUP BY expression must contain at least one column that is not an outer reference [duplicate]

This question already has answers here:
Each GROUP BY expression must contain at least one column that is not an outer reference
(8 answers)
Closed 6 years ago.
I get this error
Each GROUP BY expression must contain at least one column that is not an outer reference
while running this query:
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN
#tmpInstallParts_Temp installpartdetails ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END
) = 1
INNER JOIN
partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN
partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN
partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y' AND
ima.ipp_ID IN (SELECT ipp.ipp_id
FROM partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp ON (ipp.ipp_id = tmp.InstallingPartIPPId OR
(CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1
)
GROUP BY
ima.ipp_id
Can someone help me?
This is the text of the query from the first revision of the question.
In later revisions you removed the last closing bracket ) and the query became syntactically incorrect. You'd better check and fix the text of the question and format the text of the query, so it is readable.
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1)
GROUP BY
ima.ipp_id
)
With this formatting it is clear now that there is a subquery with GROUP BY.
Most likely it is just a typo: you meant to write GROUP BY ipp.ipp_id instead of GROUP BY ima.ipp_id.
If you really wanted to have the GROUP BY not in a subquery, but in the main SELECT, then you misplaced the closing bracket ) and the query should look like this:
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1)
)
GROUP BY
ima.ipp_id
In any case, proper formatting of the source code can really help.
Group By ima.ipp_id
should be applicable to outer query. Because of incorrect placement of '(' it was applying to inner query.
Now after correcting the query,it's working fine without any issues.
Final Query is :
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END ) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END ) =1)
)
GROUP BY ima.ipp_id
Thank you all.

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

Combine 2 rows to the same column

Hey so my query right now is
ALTER PROCEDURE [SSRS].[VolumeCustomers]
#UserID int
AS
select
CaseTypeName,
COUNT(CaseNo) as CaseCount,
'Open' as indicator
FROM ORDERS.ApCase AC with (NOLOCK)
join ORDERS.CaseType CT (NOLOCK) on CT.CaseTypeID = AC.CaseTypeID
join WORKFLOW.WorkflowHistory WH (NOLOCK) on WH.EntityID = AC.CaseID and TableID = dbo.GetTableID('ApCase', 'ORDERS') and WH.Active = 1
inner join WORKFLOW.WorkflowStep WS (NOLOCK) on WS.WorkflowStepID = WH.WorkflowStepID and WS.NextStepID is null
where (AC.Active =1 and AC.CreatedDate >= DATEADD(day,-7,getdate()) and AC.CreatedDate < GETDATE())
Group By CaseTypeName
union
select
CaseTypeName,
COUNT(Caseno) as CaseCount,
'Closed' as indicator
FROM ORDERS.ApCase AC with (NOLOCK)
join ORDERS.CaseType CT (NOLOCK) on CT.CaseTypeID = AC.CaseTypeID
join WORKFLOW.WorkflowHistory WH (NOLOCK) on WH.EntityID = AC.CaseID and TableID = dbo.GetTableID('ApCase', 'ORDERS') and WH.Active = 1
join WORKFLOW.WorkflowStep WS (NOLOCK) on WS.WorkflowStepID = WH.WorkflowStepID and WS.NextStepID is not null
where (AC.Active =1 and AC.CreatedDate >= DATEADD(day,-7,getdate()) and AC.CreatedDate < GETDATE())
GROUP BY CaseTypeName
Order by CaseCount desc
and the out put is
Cytogenetics 2 All
Cytogenetics 1 Open
Flow Tech 1 All
Flow Tech 1 Open
Surgical 1 All
Surgical 1 Open
But i want the cytogenetics, flow tech, and surgical to all appear on the same row
example:
Cytogenetics 2 All 1 Open
Flow Tech 1 All 1 Open
Surgical 1 All 1 Open
How do I edit my query to reflect this?
Does this work?
SELECT A.*, B.CaseCount, B.indicator
FROM (<First Part of Union in Question>) AS A INNER JOIN
(<Second Part of Union in Question>) AS B ON A.CaseTypeName = B.CaseTypeName
SELECT
CaseTypeName,
COUNT(CASE WHEN WS.NextStepID IS NULL THEN Caseno END) AS CaseCountOpen,
COUNT(CASE WHEN WS.NextStepID IS NOT NULL THEN Caseno END) AS CaseCountClosed,
COUNT(CaseNo) AS CaseCountAll
FROM ORDERS.ApCase AC with (NOLOCK)
JOIN ORDERS.CaseType CT (NOLOCK)
ON CT.CaseTypeID = AC.CaseTypeID
JOIN WORKFLOW.WorkflowHistory WH (NOLOCK)
ON WH.EntityID = AC.CaseID
AND TableID = dbo.GetTableID('ApCase', 'ORDERS')
AND WH.Active = 1
JOIN WORKFLOW.WorkflowStep WS (NOLOCK)
ON WS.WorkflowStepID = WH.WorkflowStepID
WHERE AC.Active = 1
AND AC.CreatedDate >= DATEADD(day,-7,getdate())
AND AC.CreatedDate < GETDATE()
GROUP BY CaseTypeName
ORDER BY CaseCountAll DESC