SQL :
select E.ID
, cp = (
select ISNULL(C.CNAME, E.CP) CP
from TBL_EXPEDITE_MASTER E
left join [NEPTUNE122].BB_PROVISION.DBO.BI_CUSTOMERS C on C.spid = E.CP
)
, E.ECO_ORDER
, E.DN
, E.CBUK
, E.XMPF_ID
, E.CP
, E.RECEIVED
, E.CP_OWNER
, E.CP_CONTACT_NUMBER
, CP_EMAIL
, E.CPREF
, E.SITE_CONTACT_NAME
, E.SITE_CONTACT_NUMBER
, E.EXISTING_CRD
, E.NEW_CRD
, E.EXPEDITE_CRD
, E.status
, E.LINE
, E.CHARGEABLE
, E.RESPONSE
, LAST_UPDATED
, ORDER_TYPE
, INITIALRESP
, NOTES
, BTW_EXPEDITE_REF --1.2
, ProductType --1.2
, InstallationAddress --1.2
, SITE_CONTACT_OTHER --1.2
, FastTrackReason --1.2
, FastTrackFOC --1.2
, FOC_Reason --1.2
, CP_EMAIL_OTHER --1.2
, Received_Via --1.2
, E2EData --1.2
, E.organisationName
, E.postCode
, E.thoroughfareDescriptor
, E.county
, E.country
from TBL_EXPEDITE_MASTER E with (nolock)
Error Message
1:
You are getting this error because in the First Select the SubQuery you are using has returned more than 1 Record for the same row.
You May try using top 1 to avoid this error or any aggregate functions or Join the subquery as a separate CTE will also work fine.
For a Quick Fix, you can change the query like this
SELECT cp =
(
SELECT TOP 1 ISNULL(C.CNAME, E.CP) CP
FROM TBL_EXPEDITE_MASTER E
LEFT JOIN [NEPTUNE122].BB_PROVISION.DBO.BI_CUSTOMERS C ON C.spid = E.CP
ORDER BY C.CNAME, E.CP
);
but looking at your query, I think this will also work
SELECT
E.ID,
cp = ISNULL(C.CNAME, E.CP),
E.ECO_ORDER,
E.DN,
E.CBUK,
E.XMPF_ID,
E.CP,
E.RECEIVED,
E.CP_OWNER,
E.CP_CONTACT_NUMBER,
CP_EMAIL,
E.CPREF,
E.SITE_CONTACT_NAME,
E.SITE_CONTACT_NUMBER,
E.EXISTING_CRD,
E.NEW_CRD,
E.EXPEDITE_CRD,
E.STATUS,
E.LINE,
E.CHARGEABLE,
E.RESPONSE,
LAST_UPDATED,
ORDER_TYPE,
INITIALRESP,
NOTES,
BTW_EXPEDITE_REF,
ProductType,
InstallationAddress,
SITE_CONTACT_OTHER,
FastTrackReason,
FastTrackFOC,
FOC_Reason,
CP_EMAIL_OTHER,
Received_Via,
E2EData,
E.organisationName,
E.postCode,
E.thoroughfareDescriptor,
E.county,
E.country
FROM TBL_EXPEDITE_MASTER E WITH (NOLOCK)
LEFT JOIN [NEPTUNE122].BB_PROVISION.DBO.BI_CUSTOMERS C
ON C.spid = E.CP
Related
I wonder if anyone has come across this behaviour before in the following query if I filter on "i.InspectionTypeID IN (x)" if x results in a large number (like about 2/3 of the entire result set of about 600 000) It takes a significantly longer amount of time to return even no results (15-30 seconds vs instantly otherwise). I can include the query and the execution plans if that helps. I can see a few differences between the queries but no idea how to refactor to improve it. We have indexes around the place that should (and have) improved performance in other places but I seem to be stuck on this one. Indexes don't appear to affect performance. At least what I tried.
Slow Query Plan: https://www.brentozar.com/pastetheplan/?id=SyBDgxSeO
EDIT: New Plan and Updated the Query as per advice from #charlieface
Here's the query:
declare #currentUserID int = 1018
declare #currentCompanyID int = 43
declare #status int = 0
declare #pageSize int = 2147483647
declare #pageNumber int = 1
DECLARE #notPreferredAssetIDsTable TABLE (id INT)
INSERT INTO #notPreferredAssetIDsTable
SELECT RecordID FROM SettingList sl
WHERE SettingID = (SELECT TOP 1 ID FROM Setting
WHERE SystemUserID = #currentUserID AND Name = 'Preferred Assets' AND Status = #status)
AND Value = '0'
AND Status = #status
SELECT i.ID As ID, a.AssetTypeID, at.Name as AssetTypeName, a.Code as AssetCode, a.Name as AssetName, CASE WHEN sections.SectionCount = 1 THEN cr.SectionName ELSE '' END as SectionName, c.Name as ContractName, reg.Name as RegionName, i.Carriageway,
startStatus.StatusDate as StartDate, startPoint.Name as StartPointName, i.ChainageFrom,
CASE WHEN i.Carriageway IS NULL THEN NULL ELSE i.ChainageFrom - (CASE WHEN i.Carriageway = 0 THEN startPoint.Forward ELSE startPoint.Reverse END) END StartDistancePast,
completedStatus.StatusDate As EndDate, endPoint.Name as EndPointName, i.ChainageTo,
CASE WHEN i.Carriageway IS NULL THEN NULL ELSE i.ChainageTo - (CASE WHEN i.Carriageway = 0 THEN endPoint.Forward ELSE endPoint.Reverse END) END EndDistancePast,
CASE WHEN i.Carriageway IS NULL THEN '' ELSE (CASE WHEN (ISNULL(OtherDirectionInspection.ID, 0) > 0) THEN 'Forward/Reverse'
WHEN i.Carriageway = 0 THEN 'Forward' ELSE 'Reverse' END) END as CarriagewayName,
dbo.GetInspectionTypeNamesForInspectionID(i.ID) AS InspectionTypeName, JobCount.Total As JobCount, i.CreatedDate,
CreatedUserName.DisplayName as CreatedUserName, AssignedUserName.DisplayName as AssignedUserName,
i.Comments, i.EntireRoad, i.PlannedDate, latestStatus.InspectionStatus AS LatestInspectionStatus, completedStatus.StatusDate AS CompletedDate, it.CompanyID as InspectionTypeCompanyID, i.ContractID, i.InspectionTypeID, sections.SectionCount,
it.Category as InspectionTypeCategory, latestStatus.ModifiedDeviceID as DeviceID, latestStatus.ModifiedUserID as LatestStatusModifiedUserID, i.JobID, i.CapitalWorkID, cw.Name as CapitalWorkName, AssignedUser.Name as AssignedUserEmail,
InspectionRouteName.Name as InspectionRouteName, i.InspectionGroupID,
il.Location AS InspectionLocation,
i.OtherDirectionInspectionID , CustomText1 , CustomBit1 , CustomDate1 , CustomNumber1 , CustomReferenceItemID1 , CustomText2 , CustomBit2 , CustomDate2 , CustomNumber2 , CustomReferenceItemID2 , CustomText3 , CustomBit3 , CustomDate3 , CustomNumber3 , CustomReferenceItemID3 , CustomText4 , CustomBit4 , CustomDate4 , CustomNumber4 , CustomReferenceItemID4 , CustomText5 , CustomBit5 , CustomDate5 , CustomNumber5 , CustomReferenceItemID5 , CustomText6 , CustomBit6 , CustomDate6 , CustomNumber6 , CustomReferenceItemID6 , CustomText7 , CustomBit7 , CustomDate7 , CustomNumber7 , CustomReferenceItemID7 , CustomText8 , CustomBit8 , CustomDate8 , CustomNumber8 , CustomReferenceItemID8 , CustomText9 , CustomBit9 , CustomDate9 , CustomNumber9 , CustomReferenceItemID9 , CustomText10 , CustomBit10 , CustomDate10 , CustomNumber10 , CustomReferenceItemID10 , CustomText11 , CustomBit11 , CustomDate11 , CustomNumber11 , CustomReferenceItemID11 , CustomText12 , CustomBit12 , CustomDate12 , CustomNumber12 , CustomReferenceItemID12 , CustomText13 , CustomBit13 , CustomDate13 , CustomNumber13 , CustomReferenceItemID13 , CustomText14 , CustomBit14 , CustomDate14 , CustomNumber14 , CustomReferenceItemID14 , CustomText15 , CustomBit15 , CustomDate15 , CustomNumber15 , CustomReferenceItemID15 , CustomText16 , CustomBit16 , CustomDate16 , CustomNumber16 , CustomReferenceItemID16 , CustomText17 , CustomBit17 , CustomDate17 , CustomNumber17 , CustomReferenceItemID17 , CustomText18 , CustomBit18 , CustomDate18 , CustomNumber18 , CustomReferenceItemID18 , CustomText19 , CustomBit19 , CustomDate19 , CustomNumber19 , CustomReferenceItemID19 , CustomText20 , CustomBit20 , CustomDate20 , CustomNumber20 , CustomReferenceItemID20 , CustomText21 , CustomBit21 , CustomDate21 , CustomNumber21 , CustomReferenceItemID21 , CustomText22 , CustomBit22 , CustomDate22 , CustomNumber22 , CustomReferenceItemID22 , CustomText23 , CustomBit23 , CustomDate23 , CustomNumber23 , CustomReferenceItemID23 , CustomText24 , CustomBit24 , CustomDate24 , CustomNumber24 , CustomReferenceItemID24 , CustomText25 , CustomBit25 , CustomDate25 , CustomNumber25 , CustomReferenceItemID25 , CustomText26 , CustomBit26 , CustomDate26 , CustomNumber26 , CustomReferenceItemID26 , CustomText27 , CustomBit27 , CustomDate27 , CustomNumber27 , CustomReferenceItemID27 , CustomText28 , CustomBit28 , CustomDate28 , CustomNumber28 , CustomReferenceItemID28 , CustomText29 , CustomBit29 , CustomDate29 , CustomNumber29 , CustomReferenceItemID29 , CustomText30 , CustomBit30 , CustomDate30 , CustomNumber30 , CustomReferenceItemID30 , CustomText31 , CustomBit31 , CustomDate31 , CustomNumber31 , CustomReferenceItemID31 , CustomText32 , CustomBit32 , CustomDate32 , CustomNumber32 , CustomReferenceItemID32 , CustomText33 , CustomBit33 , CustomDate33 , CustomNumber33 , CustomReferenceItemID33 , CustomText34 , CustomBit34 , CustomDate34 , CustomNumber34 , CustomReferenceItemID34 , CustomText35 , CustomBit35 , CustomDate35 , CustomNumber35 , CustomReferenceItemID35 , CustomText36 , CustomBit36 , CustomDate36 , CustomNumber36 , CustomReferenceItemID36 , CustomText37 , CustomBit37 , CustomDate37 , CustomNumber37 , CustomReferenceItemID37 , CustomText38 , CustomBit38 , CustomDate38 , CustomNumber38 , CustomReferenceItemID38 , CustomText39 , CustomBit39 , CustomDate39 , CustomNumber39 , CustomReferenceItemID39 , CustomText40 , CustomBit40 , CustomDate40 , CustomNumber40 , CustomReferenceItemID40 , CustomText41 , CustomBit41 , CustomDate41 , CustomNumber41 , CustomReferenceItemID41 , CustomText42 , CustomBit42 , CustomDate42 , CustomNumber42 , CustomReferenceItemID42 , CustomText43 , CustomBit43 , CustomDate43 , CustomNumber43 , CustomReferenceItemID43 , CustomText44 , CustomBit44 , CustomDate44 , CustomNumber44 , CustomReferenceItemID44 , CustomText45 , CustomBit45 , CustomDate45 , CustomNumber45 , CustomReferenceItemID45 , CustomText46 , CustomBit46 , CustomDate46 , CustomNumber46 , CustomReferenceItemID46 , CustomText47 , CustomBit47 , CustomDate47 , CustomNumber47 , CustomReferenceItemID47 , CustomText48 , CustomBit48 , CustomDate48 , CustomNumber48 , CustomReferenceItemID48 , CustomText49 , CustomBit49 , CustomDate49 , CustomNumber49 , CustomReferenceItemID49 , CustomText50 , CustomBit50 , CustomDate50 , CustomNumber50 , CustomReferenceItemID50
FROM Inspection i
INNER JOIN InspectionType it On i.InspectionTypeID = it.ID
INNER JOIN SystemUser CreatedUser On CreatedUser.ID = i.CreatedUserID
INNER JOIN Contract c On i.ContractID = c.ID
INNER JOIN Region reg On c.RegionID = reg.ID
INNER JOIN InspectionLocation il ON il.InspectionID = i.ID
LEFT OUTER JOIN Asset a On i.AssetID = a.ID
LEFT OUTER JOIN SystemUser AssignedUser On AssignedUser.ID = i.AssignedUserID
LEFT OUTER JOIN Road r On i.RoadID = r.ID
LEFT OUTER JOIN AssetType at On it.AssetTypeID = at.ID
LEFT OUTER JOIN Point startPoint On i.StartPointID = startPoint.ID
LEFT OUTER JOIN Point endPoint On i.EndPointID = endPoint.ID
LEFT OUTER JOIN CapitalWork cw On i.CapitalWorkID = cw.ID
CROSS APPLY dbo.GetNameForUser_Inline(i.CreatedUserID, i.ContractID, #currentCompanyID, 0) As CreatedUserName
OUTER APPLY dbo.GetNameForUser_Inline(i.AssignedUserID, i.ContractID, #currentCompanyID, 0) As AssignedUserName
OUTER APPLY
(
SELECT TOP 1 SectionName
FROM ContractRoad cr
WHERE cr.RoadID = r.ID
AND cr.ContractID = i.ContractID
AND ((i.Carriageway = 0 AND i.ChainageFrom < cr.ChainageToForward AND cr.ChainageFromForward < i.ChainageTo)
OR (i.Carriageway = 1 AND i.ChainageFrom < cr.ChainageFromReverse AND cr.ChainageToReverse < i.ChainageTo))
AND cr.Status = #status
) cr
OUTER APPLY
(
SELECT count(SectionName) as SectionCount
FROM ContractRoad cr
WHERE cr.RoadID = r.ID
AND cr.ContractID = i.ContractID
AND ((i.Carriageway = 0 AND i.ChainageFrom < cr.ChainageToForward AND cr.ChainageFromForward < i.ChainageTo)
OR (i.Carriageway = 1 AND i.ChainageFrom < cr.ChainageFromReverse AND cr.ChainageToReverse < i.ChainageTo))
AND cr.Status = #status
) sections
OUTER APPLY
(
SELECT TOP 1 StatusDate, LocalTime.LocalTime as StatusDateLocal
FROM InspectionStatus
CROSS APPLY tzdb.UtcToLocal_Inline(StatusDate, 'Australia/Sydney') as LocalTime
WHERE Status = #status
AND InspectionID = i.ID
AND InspectionStatus = 1
ORDER BY StatusDate
) startStatus
OUTER APPLY
(
SELECT TOP 1 StatusDate, LocalTime.LocalTime as StatusDateLocal
FROM InspectionStatus
CROSS APPLY tzdb.UtcToLocal_Inline(StatusDate, 'Australia/Sydney') as LocalTime
WHERE Status = #status
AND InspectionID = i.ID
AND InspectionStatus = 5
ORDER BY StatusDate
) completedStatus
OUTER APPLY
(
SELECT TOP 1 ID, StatusDate, InspectionStatus, ModifiedDeviceID, ModifiedUserID
FROM InspectionStatus
WHERE Status = #status AND InspectionStatus.InspectionStatus <> 7
AND InspectionID = i.ID
ORDER BY CASE WHEN InspectionStatus.InspectionStatus = 6 THEN 1 ELSE 0 END, StatusDate DESC
) latestStatus
OUTER APPLY
(
SELECT COUNT(ID) As Total FROM Job
WHERE InspectionID = i.ID
AND ParentJobID IS NULL
AND Status = #status
) JobCount
OUTER APPLY
(
SELECT i2.ID
FROM dbo.Inspection i2
WHERE i2.OtherDirectionInspectionID = i.ID
AND Status = #status
) OtherDirectionInspection
OUTER APPLY
(
SELECT TOP 1 ir.Name FROM InspectionRoute ir
INNER JOIN InspectionGroup ig ON ig.InspectionRouteID = ir.ID
WHERE ir.Status = 0
AND ir.CompanyID = 43
AND ig.Status = 0
AND ig.ID = i.InspectionGroupID
) InspectionRouteName
WHERE i.Status = 0 AND i.ParentInspectionID IS NULL
AND il.Status = 0
--AND ((i.AssetID IS NOT NULL AND i.AssetID NOT IN (SELECT ID FROM #notPreferredAssetIDsTable)) OR i.AssetID IS NULL)
AND it.Category <> 2
AND c.IsArchived = 0
AND it.AssetTypeID = 3 AND a.AssetTypeID IS NOT NULL AND a.AssetTypeID = 3
AND i.InspectionTypeID IN (3)
AND i.ContractID IN (90,118)
AND (latestStatus.InspectionStatus IN (5,6,1,2,3) OR completedStatus.StatusDate IS NOT NULL OR latestStatus.InspectionStatus IS NULL)
AND ((completedStatus.StatusDateLocal >= '2021-02-01 00:00:00' AND completedStatus.StatusDateLocal <= '2021-02-05 23:59:59') OR (i.PlannedDate >= '2021-02-01 00:00:00' AND i.PlannedDate <= '2021-02-05 23:59:59') OR (i.CreatedDate >= '2021-02-01 00:00:00' AND i.CreatedDate <= '2021-02-05 23:59:59' AND (latestStatus.InspectionStatus not in (6, 5) OR latestStatus.InspectionStatus IS NULL)))
AND ((CASE WHEN i.AssignedUserID IS NULL THEN CreatedUser.CompanyID ELSE AssignedUser.CompanyID END = 43) OR (CASE WHEN i.AssignedUserID IS NULL THEN CreatedUser.CompanyID ELSE AssignedUser.CompanyID END = 1
AND i.ContractID IN (90,118)) OR (CASE WHEN i.AssignedUserID IS NULL THEN CreatedUser.CompanyID ELSE AssignedUser.CompanyID END = 79
AND i.ContractID IN (90)) OR (CASE WHEN i.AssignedUserID IS NULL THEN CreatedUser.CompanyID ELSE AssignedUser.CompanyID END = 80
AND i.ContractID IN (90)) OR (CASE WHEN i.AssignedUserID IS NULL THEN CreatedUser.CompanyID ELSE AssignedUser.CompanyID END = 81
AND i.ContractID IN (90)) OR (CASE WHEN i.AssignedUserID IS NULL THEN CreatedUser.CompanyID ELSE AssignedUser.CompanyID END = 82
AND i.ContractID IN (90)))
ORDER BY ID
OFFSET #pageSize * (#pageNumber - 1) ROWS
FETCH NEXT #pageSize ROWS ONLY
OPTION (RECOMPILE)
I have the following View:
So the question is,How to Improve SQL readability of this query?
SELECT t1.Id ,
t1.HeaderRef ,
t1.PartRef ,
t1.SLRef ,
t1.DL ,
t1.DL2 ,
t1.DL3 ,
t1.DL4 ,
t1.DL5 ,
t1.DL6 ,
t1.DL7 ,
t1.ItemRef ,
t1.CalItemRef ,
t1.RowNum ,
t1.UnitType ,
t1.UnitTypeTitle ,
t1.UnitRef ,
t1.Ratio ,
t1.Value ,
t1.MasterValue ,
t1.ItemDate ,
t1.Descript ,
t1.Year ,
t1.BranchRef ,
t1.StockRef ,
t1.OpositStockRef ,
t1.DocTypeRef ,
t1.BaseDocTypeRef ,
t1.Creator ,
t1.Confirmer ,
t1.Num ,
t1.State ,
t1.DocDate ,
t1.FCRef ,
t1.FCTitle ,
t1.PartTitle ,
t1.PartCode ,
t1.SLCode ,
t1.DL1Code ,
t1.DL2Code ,
t1.DL3Code ,
t1.DL4Code ,
t1.DL5Code ,
t1.DL6Code ,
t1.DL7Code ,
t1.UnitTitle ,
t1.PartUnitTitle ,
( ( AVG(t1.RealPrice) + SUM(t1.CorrectPrice) ) / t1.Value ) AS CorrectRate ,
AVG(t1.RealPrice) + SUM(t1.CorrectPrice) AS CorrectPrice ,
MAX(t1.CorrectAccDocHeaderRef) AS CorrectAccDocHeaderRef ,
1 AS CorrectCreator ,
1 AS CorrectConfirmer ,
MAX(t1.CorrectCreateDate) AS CorrectCreateDate ,
GETDATE() AS CorrectConfirmDate ,
CorrectFCRate = ( SELECT MAX(rr.FCRate)
FROM Stc.StcDocRate AS rr
WHERE rr.ItemRef = t1.Id
AND rr.PriceType = '2'
AND CreateDate = MAX(t1.CorrectCreateDate)
) ,
CorrectFCVal = ( SELECT MAX(rr.FCVal)
FROM Stc.StcDocRate AS rr
WHERE rr.ItemRef = t1.Id
AND rr.PriceType = '2'
AND CreateDate = MAX(t1.CorrectCreateDate)
),
CorrectDescript = ( SELECT MAX(Descript)
FROM Stc.StcDocRate AS rr
WHERE rr.ItemRef = t1.Id
AND rr.PriceType = '2'
AND CreateDate = MAX(t1.CorrectCreateDate)
) ,
AVG(t1.RealPrice) / t1.Value AS RealRate ,
AVG(t1.RealPrice) AS RealPrice ,
MAX(t1.RealAccDocHeaderRef) AS RealAccDocHeaderRef ,
1 AS RealCreator ,
1 AS RealConfirmer ,
GETDATE() AS RealCreateDate ,
GETDATE() AS RealConfirmDate ,
AVG(t1.RealFCRate) AS RealFCRate ,
AVG(t1.RealFCVal) AS RealFCVal ,
AVG(t1.CaledPrice) / t1.Value AS CaledRate ,
AVG(t1.CaledPrice) AS CaledPrice ,
MAX(t1.CaledAccDocHeaderRef) AS CaledAccDocHeaderRef ,
1 AS CaledCreator ,
1 AS CaledConfirmer ,
GETDATE() AS CaledCreateDate ,
GETDATE() AS CaledConfirmDate ,
AVG(t1.CaledFCRate) AS CaledFCRate ,
AVG(t1.CaledFCVal) AS CaledFCVal ,
t1.ItemNum ,
t1.BasePartCode ,
t1.BasePartTitle ,
t1.DlRefHeader ,
t1.SLRefHeader,
t1.ProductionValue ,
t1.FormulaRef ,
t1.StcDocReqRef
FROM ( SELECT item.Id ,
item.HeaderRef ,
item.PartRef ,
item.SLRef ,
item.DL ,
item.DL2 ,
item.DL3 ,
item.DL4 ,
item.DL5 ,
item.DL6 ,
item.DL7 ,
item.ItemRef ,
item.CalItemRef ,
item.RowNum ,
item.UnitType ,
UnitTypeTitle = CASE item.UnitType
WHEN '1' THEN N'اصلی'
WHEN '2' THEN N'فرعی'
END ,
item.UnitRef ,
item.Ratio ,
item.Value ,
item.MasterValue ,
item.ItemDate ,
item.Descript ,
item.StcDocReqRef ,
item.Year ,
item.BranchRef ,
item.StockRef ,
item.OpositStockRef ,
item.DocTypeRef ,
item.BaseDocTypeRef ,
item.Creator ,
item.Confirmer ,
item.Num ,
item.State ,
item.DocDate ,
item.FCRef ,
fc.Title AS FCTitle ,
item.ProductionValue ,
item.FormulaRef ,
p.Title AS PartTitle ,
p.Code AS PartCode ,
sl.SLCode AS SLCode ,
dl1.DLCode AS DL1Code ,
dl2.DLCode AS DL2Code ,
dl3.DLCode AS DL3Code ,
dl4.DLCode AS DL4Code ,
dl5.DLCode AS DL5Code ,
dl6.DLCode AS DL6Code ,
dl7.DLCode AS DL7Code ,
pu.Title AS UnitTitle ,
puslave.Title AS PartUnitTitle ,
CorrectRate.Rate AS CorrectRate ,
CorrectRate.Price AS CorrectPrice ,
CorrectRate.AccDocHeaderRef AS CorrectAccDocHeaderRef ,
CorrectRate.Creator AS CorrectCreator ,
CorrectRate.Confirmer AS CorrectConfirmer ,
CorrectRate.CreateDate AS CorrectCreateDate ,
CorrectRate.ConfirmDate AS CorrectConfirmDate ,
CorrectRate.FCRate AS CorrectFCRate ,
CorrectRate.FCVal AS CorrectFCVal ,
CorrectRate.Descript AS CorrectDescript ,
realRate.Rate RealRate ,
realRate.Price RealPrice ,
realRate.AccDocHeaderRef AS RealAccDocHeaderRef ,
realRate.Creator AS RealCreator ,
realRate.Confirmer AS RealConfirmer ,
realRate.CreateDate AS RealCreateDate ,
realRate.ConfirmDate AS RealConfirmDate ,
realRate.FCRate AS RealFCRate ,
realRate.FCVal AS RealFCVal ,
CaledRate.Rate AS CaledRate ,
CaledRate.Price AS CaledPrice ,
CaledRate.AccDocHeaderRef AS CaledAccDocHeaderRef ,
CaledRate.Creator AS CaledCreator ,
CaledRate.Confirmer AS CaledConfirmer ,
CaledRate.CreateDate AS CaledCreateDate ,
CaledRate.ConfirmDate AS CaledConfirmDate ,
CaledRate.FCRate AS CaledFCRate ,
CaledRate.FCVal AS CaledFCVal ,
ItemNum = CASE header.BaseDocTypeRef
WHEN 2000 THEN refReqItem.Num
WHEN 2002 THEN refOrderItem.Num
WHEN 2003 THEN refFactItem.Num
WHEN 2004 THEN refRetFactItem.Num
WHEN 2010 THEN cmrPostItem.Num
WHEN 2012 THEN cmrRet.Num
WHEN 2016 THEN header.ProductionNum
ELSE refItem.Num
END ,
refPart.Code AS BasePartCode ,
refPart.Title AS BasePartTitle ,
header.DLRef AS DlRefHeader ,
header.SLRef AS SLRefHeader
FROM Stc.StcDocItem AS item
INNER JOIN Stc.Part AS p ON p.Id = item.PartRef
LEFT OUTER JOIN Acc.SL AS sl ON sl.Id = item.SLRef
LEFT OUTER JOIN Acc.DL AS dl1 ON dl1.Id = item.DL
LEFT OUTER JOIN Acc.DL AS dl2 ON dl2.Id = item.DL2
LEFT OUTER JOIN Acc.DL AS dl3 ON dl3.Id = item.DL3
LEFT OUTER JOIN Acc.DL AS dl4 ON dl4.Id = item.DL4
LEFT OUTER JOIN Acc.DL AS dl5 ON dl5.Id = item.DL5
LEFT OUTER JOIN Acc.DL AS dl6 ON dl6.Id = item.DL6
LEFT OUTER JOIN Acc.DL AS dl7 ON dl7.Id = item.DL7
LEFT OUTER JOIN Acc.FC AS fc ON fc.Id = item.FCRef
LEFT OUTER JOIN Stc.PartUnit AS pu ON pu.Id = item.UnitRef
LEFT OUTER JOIN Stc.PartUnit AS puslave ON puslave.Id = p.UnitRef
LEFT OUTER JOIN Stc.StcDocRate AS realRate ON realRate.ItemRef = item.Id
AND realRate.PriceType = '1'
LEFT OUTER JOIN Stc.StcDocRate AS CorrectRate ON CorrectRate.ItemRef = item.Id
AND CorrectRate.PriceType = '2'
LEFT OUTER JOIN Stc.StcDocRate AS CaledRate ON CaledRate.ItemRef = item.Id
AND CaledRate.PriceType = '3'
LEFT OUTER JOIN Stc.StcDocItem AS refItem ON refItem.Id = item.ItemRef
LEFT OUTER JOIN Stc.Part AS refPart ON refItem.PartRef = refPart.Id
LEFT OUTER JOIN Stc.StcDocReqItem AS refReqItem ON refReqItem.Id = item.ItemRef
LEFT OUTER JOIN Sle.SleDocOrderItem AS refOrderItem ON refOrderItem.Id = item.ItemRef
LEFT OUTER JOIN Sle.SleDocFactItem AS refFactItem ON refFactItem.Id = item.ItemRef
LEFT OUTER JOIN Sle.SleDocRetFactItem AS refRetFactItem ON refRetFactItem.Id = item.ItemRef
LEFT OUTER JOIN CMR.CMRIntSheetPostItem AS cmrPostItem ON cmrPostItem.Id = item.ItemRef
LEFT OUTER JOIN CMR.CMRIntReturnPartNonConformingItem
AS cmrRet ON cmrRet.Id = item.ItemRef
LEFT OUTER JOIN Stc.StcDocHeader AS header ON header.Id = item.HeaderRef
) AS t1
Readability of this query is pretty bad. In particular, i had problem to understand.
I would like some feedback how to improve performance and Readability for this case?
1. readability
if you have to get one output select with all this columns, your query is well formed enough
if you can decompose your qry, so split it into smaller logical (or semantically connected) blocks
use views for pivoted output - for example instead of 8x Acc.SL left join create view with pivoted data
use functions or views to remove case statement or subqueries
separate agregations and other data (it seems in your qry is missing group by statement)
2. performance
get query plan
rewrite your query to use existing indexes or add missing indexes
force joins order if it's necessary
I have a query like below, but ShowRoomName and UnitNameare not shown in the result. How can I solve it?
SELECT A.ShowRoomId
, Sum(B.BasicAmount) AS TotalBasic
, Sum(B.HouseAmount) AS TotalHouseAmount
, Sum(B.MedicaleAmount) AS TotalMedicaleAmount
, Sum(B.ConvenceAmount) AS TotalConvenceAmount
, Sum(B.PhoneBillAmount) AS TotalPhoneBillAmount
, Sum(B.DirectorRemuneration) AS TotalDirectorRemuneration
, Sum(B.OthersAmount) AS TotalOthersAmount
FROM Employees A
OUTER APPLY (SELECT TOP 1 *
FROM EmployeeBasics B
WHERE ( A.EmployeeID = B.EmployeeID )
ORDER BY B.BasicUpdateDate DESC) AS B
OUTER APPLY (SELECT ShowRoomId
, ShowRoomName
, UnitId
FROM dbo.ShowRooms C
WHERE A.ShowRoomId = C.ShowRoomId) AS C
OUTER APPLY (SELECT UnitId
, UnitName
FROM dbo.Units D
WHERE C.UnitId = D.UnitId) AS D
GROUP BY A.SHowRoomId
use a more descriptive title when you ask a question. query not
working describes basically 99% of all questions.
your unit name and
showroomname dont appear because you dont select them...
I am guessing that you want something like this. Notice I changed your aliases into something meaningful. Using A, B, C is a bad habit for aliases. It is challenging to maintain code like that.
SELECT e.ShowRoomId
, Sum(eb.BasicAmount) AS TotalBasic
, Sum(eb.HouseAmount) AS TotalHouseAmount
, Sum(eb.MedicaleAmount) AS TotalMedicaleAmount
, Sum(eb.ConvenceAmount) AS TotalConvenceAmount
, Sum(eb.PhoneBillAmount) AS TotalPhoneBillAmount
, Sum(eb.DirectorRemuneration) AS TotalDirectorRemuneration
, Sum(eb.OthersAmount) AS TotalOthersAmount
, sr.ShowRoomName
, u.UnitName
FROM Employees e
OUTER APPLY
(
SELECT TOP 1 *
FROM EmployeeBasics eb1
WHERE e.EmployeeID = eb1.EmployeeID
ORDER BY eb1.BasicUpdateDate DESC
) AS eb
LEFT JOIN ShowRooms sr ON sr.ShowRoomId = e.ShowRoomId
LEFT JOIN Units u ON u.UnitID = sr.UnitID
GROUP BY e.SHowRoomId
, sr.ShowRoomName
, u.UnitName
I'm using MS Visual Studio 2012. I'm having an issue with writing a subquery. This is the entire query as follows:
SELECT ACCOUNTNUM
, NAME
, ADDRESS
, PHONE
, TELEFAX
, INVOICEACCOUNT
, CUSTGROUP
, PAYMTERMID
, CURRENCY
, DIMENSION
, CELLULARPHONE
, STATISTICSGROUP
, PAYMMODE
, NAMEALIAS
, CONTACTPERSONID
, STREET
, PARTYID
, SEGMENTID
, TAXGROUP
, DATAAREAID
, ISNULL((
SELECT PERCENT1 AS DiscCount
FROM PRICEDISCTABLE
WHERE (DATAAREAID = CUSTTABLE.DATAAREAID)
AND (ACCOUNTRELATION = CUSTTABLE.ACCOUNTNUM)
), 0) / 100 AS DiscCount
, (
SELECT NAME
FROM CONTACTPERSON
WHERE (DATAAREAID = CUSTTABLE.DATAAREAID)
AND (CUSTACCOUNT = CUSTTABLE.ACCOUNTNUM)
AND (CONTACTPERSONID = CUSTTABLE.CONTACTPERSONID)
) AS ContactName
, (
SELECT PHONE
FROM CONTACTPERSON AS CONTACTPERSON_1
WHERE (DATAAREAID = CUSTTABLE.DATAAREAID)
AND (CUSTACCOUNT = CUSTTABLE.ACCOUNTNUM)
AND (CONTACTPERSONID = CUSTTABLE.CONTACTPERSONID)
) AS ContactPhone
, ISNULL((
SELECT STATGROUPNAME
FROM CUSTSTATISTICSGROUP
WHERE (DATAAREAID = CUSTTABLE.DATAAREAID)
AND (CUSTSTATISTICSGROUP = CUSTTABLE.STATISTICSGROUP)
), 0) AS StatisticsName
FROM CUSTTABLE
WHERE CUSTGROUP = #ty
AND DATAAREAID = N'OTN'
AND STATISTICSGROUP LIKE #ss;
and then I get the error
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
Where the issue comes from?
Issue is that one of your subqueries returns more than one value (HEY, ERROR DESCRIPTION SAYS THAT).
How to find which one?
Try commenting out each subquery in your select statement until your query works fine.
How to fix it?
That's probably the best case to use CROSS APPLY. That'd be your query:
SELECT ACCOUNTNUM
, NAME
, ADDRESS
, PHONE
, TELEFAX
, INVOICEACCOUNT
, CUSTGROUP
, PAYMTERMID
, CURRENCY
, DIMENSION
, CELLULARPHONE
, STATISTICSGROUP
, PAYMMODE
, NAMEALIAS
, CONTACTPERSONID
, STREET
, PARTYID
, SEGMENTID
, TAXGROUP
, DATAAREAID
, ISNULL(T1.DiscCount, 0) / 100 AS DiscCount
, T2.ContactName
, T3.ContactPhone
, ISNULL(T4, 0) AS StatisticsName
FROM CUSTTABLE
CROSS APPLY (
SELECT PERCENT1 AS DiscCount
FROM PRICEDISCTABLE
WHERE DATAAREAID = CUSTTABLE.DATAAREAID
AND ACCOUNTRELATION = CUSTTABLE.ACCOUNTNUM
) AS T1
CROSS APPLY (
SELECT NAME
FROM CONTACTPERSON
WHERE DATAAREAID = CUSTTABLE.DATAAREAID
AND CUSTACCOUNT = CUSTTABLE.ACCOUNTNUM
AND CONTACTPERSONID = CUSTTABLE.CONTACTPERSONID
) AS T2
CROSS APPLY (
SELECT PHONE
FROM CONTACTPERSON AS CONTACTPERSON_1
WHERE DATAAREAID = CUSTTABLE.DATAAREAID
AND CUSTACCOUNT = CUSTTABLE.ACCOUNTNUM
AND CONTACTPERSONID = CUSTTABLE.CONTACTPERSONID
) AS T3
CROSS APPLY (
SELECT STATGROUPNAME
FROM CUSTSTATISTICSGROUP
WHERE DATAAREAID = CUSTTABLE.DATAAREAID
AND CUSTSTATISTICSGROUP = CUSTTABLE.STATISTICSGROUP
) AS T4
WHERE CUSTGROUP = #ty
AND DATAAREAID = N'OTN'
AND STATISTICSGROUP LIKE #ss;
Also, these can be rewritten as simple INNER JOINS.
When encountering this error, try running the subqueries individually and if more than one record is returned then refine your conditions to ensure only one record is returned.
Of course, if more than one record is wanted then you need to change your query to use a join instead of a subquery.
work on sql-server-2005
SELECT A.specific_customization_id ,
A.customization_id ,
A.customization_value ,
A.customization_price ,
A.customization_cost ,
A.customization_code ,
A.customization_check ,
A.sort_order ,
A.option_code ,
A.product_id ,
A.image_1 ,
A.image_2 ,
A.MainProductID ,
A.customization_product_id ,
A.inactive ,
A.customization_description ,
A.customization_select ,
A.UOM ,
A.allow_recur ,
auto_reorder = CASE A.MainProductID --it's an int type column
WHEN NULL THEN A.allow_recur
ELSE ( SELECT allow_recur
FROM wc_product
WHERE product_id = A.MainProductID
)
END
FROM dbo.wc_product_specific A
WHERE A.product_id = 1133
Using the above query I want to set auto_reorder column value .want to set two login
When My MainProductID column is null I want to set allow_recur column value
When it’s not null I want to set another table column value
My logic 2) works fine ,fail to understand why does 1) not work? Help me to fix the problem?
If have any query plz ask thanks in advance.
Does this work:?
SELECT A.specific_customization_id ,
A.customization_id ,
A.customization_value ,
A.customization_price ,
A.customization_cost ,
A.customization_code ,
A.customization_check ,
A.sort_order ,
A.option_code ,
A.product_id ,
A.image_1 ,
A.image_2 ,
A.MainProductID ,
A.customization_product_id ,
A.inactive ,
A.customization_description ,
A.customization_select ,
A.UOM ,
A.allow_recur ,
A.auto_reorder = CASE --it's an int type column
WHEN A.MainProductID IS NULL THEN A.allow_recur
ELSE B.allow_recur
END
FROM dbo.wc_product_specific A
left outer join wc_product B on B.product_id = A.MainProductID
WHERE A.product_id = 1133