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 need some help mimicking a TFS query.
I have tried writing the following SQL query to do so but I am not able to get a matching population:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF OBJECT_ID('tempdb.dbo.#LastRecord') IS NOT NULL DROP TABLE #LastRecord
SELECT System_Id
, LastUpdatedDateTime = MAX(LastUpdatedDateTime)
INTO #LastRecord
FROM [dimWorkItem]
GROUP BY System_Id
SELECT distinct ID = w.System_Id
--Cannot find Department
, Department = '?'
, w.TeamProjectSK
, RequestedByUser = w.Custom_RequestedBy
, Title = w.System_Title
, [Priority] = w.Microsoft_VSTS_Common_Priority
, Activity = w.Microsoft_VSTS_Common_Activity
, da.AreaPath
, [State] = w.System_State
, Reason = w.System_Reason
, ClosedDate = w.Microsoft_VSTS_Common_ClosedDate
, ActivatedDate = Microsoft_VSTS_Common_ActivatedDate
, DevHours = Custom_DevHours
, CreatedDate = w.System_CreatedDate
, AssignedTo = dp.Name
, [Week] = CASE WHEN (w.System_State = 'Active' OR Microsoft_VSTS_Common_ClosedDate >= dateadd(d,-7,CONVERT(Date,getdate(),1))) THEN 'Current'
WHEN (w.System_State = 'Active' OR Microsoft_VSTS_Common_ClosedDate >= dateadd(d,-14,CONVERT(Date,getdate(),1)) AND Microsoft_VSTS_Common_ClosedDate < dateadd(d,-7,CONVERT(Date,getdate(),1))) THEN 'Last'
ELSE 'Previous' END
, TSRNumber = Custom_TSRNumber
FROM
(Select * from (select *, rn = row_number() over(partition by w1.System_Id, w1.TeamProjectSK, w1.System_State order by w1.System_Rev desc)
from dbo.DimWorkItem w1) d where rn = 1) w
JOIN #LastRecord l ON w.System_Id = l.System_Id AND w.LastUpdatedDateTime = l.LastUpdatedDateTime
LEFT OUTER JOIN dbo.DimArea da ON w.AreaSK = da.AreaSK
LEFT OUTER JOIN DimPerson dp ON w.System_AssignedTo__PersonSK = dp.PersonSK
WHERE System_WorkItemType = 'Task'
AND da.AreaPath like '\LOS\Reporting%'
AND w.Microsoft_VSTS_Common_Priority < 4
Also if anyone knows where I could find the department field as I am not sure whether it is a custom field or not.
SQL Server 2014: 12.0
TFS: 12.0
Visual studio professional 2015: 14.0
Thank you in advance for your suggestions!
I found a solution although still not able to find the the Department field :
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF OBJECT_ID('tempdb.dbo.#LastRecord') IS NOT NULL DROP TABLE #LastRecord
SELECT System_Id, LastChangedDate = MAX(System_ChangedDate)
INTO #LastRecord
FROM [dimWorkItem]
GROUP BY System_Id
DECLARE #FromDateWeek DATE
DECLARE #FromDateTwoWeek DATE
SET #FromDateWeek = dateadd(d,-7,CONVERT(Date,getdate(),1))
SET #FromDateTwoWeek = dateadd(d,-14,CONVERT(Date,getdate(),1))
--SELECT #FromDate
SELECT ID = w.System_Id
--Cannot find Department
, Department = '?'
, w.TeamProjectSK
, RequestedByUser = w.Custom_RequestedBy
, Title = w.System_Title
, [Priority] = w.Microsoft_VSTS_Common_Priority
, Activity = w.Microsoft_VSTS_Common_Activity
, da.AreaPath
, [State] = w.System_State
, Reason = w.System_Reason
, ClosedDate = w.Microsoft_VSTS_Common_ClosedDate
, ActivatedDate = Microsoft_VSTS_Common_ActivatedDate
, DevHours = Custom_DevHours
, CreatedDate = w.System_CreatedDate
, AssignedTo = dp.Name
, [Week] = CASE WHEN w.Microsoft_VSTS_Common_ClosedDate >= #FromDateWeek OR w.System_State = 'Active' THEN 'Current'
WHEN (w.Microsoft_VSTS_Common_ClosedDate >= #FromDateTwoWeek AND w.Microsoft_VSTS_Common_ClosedDate < #FromDateWeek)
OR w.Microsoft_VSTS_Common_ClosedDate < #FromDateWeek THEN 'Last'
ELSE 'Previous' END
FROM [dimWorkItem] w
JOIN #LastRecord l ON w.System_Id = l.System_Id AND w.System_ChangedDate = l.LastChangedDate
LEFT OUTER JOIN DimPerson dp ON w.System_AssignedTo__PersonSK = dp.PersonSK
LEFT OUTER JOIN dbo.DimArea da ON w.AreaSK = da.AreaSK
WHERE
da.AreaPath LIKE '\LOS\Reporting%'
AND System_WorkItemType = 'Task'
AND (Microsoft_VSTS_Common_ClosedDate >= #FromDateTwoWeek
OR w.System_State = 'Active')
AND ISNULL(Microsoft_VSTS_Common_Priority,0) < 4
AND w.System_Reason <> 'Obsolete'
i have an sp that i check if user's password change date has 14 days
left(flag=0) and i send email to that users and i that sp i check(by a
col.flag) if email already sent or not.after that i update the the
flag col.in an another SP(ExpiryNotificationFlag) to 1 of users list whose email has
already sent..now i don't know how to check for 7,3,2,1 days as flag
col value is already 1 ?
sp
SELECT TenantName
, TenantEmail
, GMAP_code
, ContactID FROM (
SELECT b_1.TenantName
, b_1.TenantEmail
, LastPDWChangeDate =(SELECT ISNULL(max (DateChanged),GETDATE()) FROM dbo.wsm_Contact_PwdHistory WHERE ContactID = b_1.TenantRegContactID)
, ExpiryNotificationFlag =(SELECT top 1 ExpiryNotificationFlag FROM dbo.wsm_Contact_PwdHistory WHERE ContactID = b_1.TenantRegContactID order by DateChanged desc)
, GMAP_code =(SELECT TOP 1 ISNULL(GMAP_CODE,'') from wsm_Ref_Buildings where BuildingId = b_1.BuildingID)
, b_1.TenantRegContactID as ContactID
FROM dbo.wsm_Contact AS a LEFT OUTER JOIN
(
SELECT C.Name AS TenantName
, A.SiteID
, A.BuildingID
, A.FloorID
, A.ContactID AS TenantRegContactID
, D.LEASID
, C.Phone AS TenantPhone
, C.Email AS TenantEmail
, B.UserID AS userid
, C.Mobile AS TenantMobile
, B.UserType
FROM dbo.wsm_Contact_Tenancy AS A
INNER JOIN dbo.wsm_Contact_User AS B ON A.ContactID = B.ContactID AND B.Active = 1
INNER JOIN dbo.wsm_Contact AS C ON B.ContactID = C.ContactID
INNER JOIN (
SELECT DISTINCT COALESCE (LEASID, ExtLeasNum) AS LEASID
, SiteID
, BuildingID
, FloorID
FROM dbo.wsm_Contact) AS D ON A.SiteID = D.SiteID AND A.BuildingID = D.BuildingID AND A.FloorID = D.FloorID) AS b_1 ON
COALESCE (a.LEASID, a.ExtLeasNum) = b_1.LEASID AND a.SiteID = b_1.SiteID AND a.BuildingID = b_1.BuildingID AND a.FloorID = b_1.FloorID
INNER JOIN dbo.wsm_Ref_Floors AS C ON a.FloorID = C.FloorId
WHERE (a.OCCPSTAT NOT IN ('I', 'P')) and C.Deleted = 0 and b_1.userid is not null ) AS A WHERE DATEDIFF(DAY,A.LastPDWChangeDate,getdate()) = 76 AND ISNULL(ExpiryNotificationFlag,0) <> 1
END
update Query
UPDATE dbo.wsm_Contact_PwdHistory set ExpiryNotificationFlag = 1 WHERE ContactID = #ContactID
you can do it like that
( (DATEDIFF(DAY,A.LastPDWChangeDate,getdate()) = 76 AND ISNULL(ExpiryNotificationFlag,0) = 0) --14 days
or (DATEDIFF(DAY,A.LastPDWChangeDate,getdate()) = 83 AND ISNULL(ExpiryNotificationFlag,0) = 1) --7days
or (DATEDIFF(DAY,A.LastPDWChangeDate,getdate()) = 87 AND ISNULL(ExpiryNotificationFlag,0) = 2) --3 days
or (DATEDIFF(DAY,A.LastPDWChangeDate,getdate()) = 88 AND ISNULL(ExpiryNotificationFlag,0) = 3) --2 days
or (DATEDIFF(DAY,A.LastPDWChangeDate,getdate()) = 89 AND ISNULL(ExpiryNotificationFlag,0) = 4) --1 day
)
for that u have to modify Expiry notification flag to int instead of a Boolean
after that make a SP where will u update the value from
0 to 1,1 to 2,2 to 3 etc.
Youre essentially making the following complaint:
"A boolean datatype can only store one of two values!"
Indeed, so swap out that flag for a "Number of Days Left" column, and compare it to 14, 7, whatever....
Note, ExpiryNotificationFlag column isn't a great name - how about "PasswordExpiryEmailSent"
Sometimes these problems get a lot easier to think about when the columns have better names
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