PL/SQL to T-SQL conversion error - sql

Working to convert the following statement to T-SQL from PL/SQL (Work in progress). However I've run into an error in SQL Server.
SELECT COUNT(*) OVER() AS RW_CNT
,COUNT(*) OVER( PARTITION BY(P.PLACEMENT_HISTORY_ID)) AS DP_CNT
,P.PLACEMENT_HISTORY_ID AS DD_PLCMT_HIST_ID
,U.ES_PARTICIPANT_KEY
,A.ES_PARTICIPANT_ATTR_KEY
,ISNULL(CENTER.ES_ORG_KEY, 0) AS ES_CENTER_ORG_KEY
,ISNULL(O.ES_ORG_KEY, 0) AS ES_LOCAL_UNIT_KEY
,ISNULL(STK.ES_ORG_KEY, 0) AS ES_STAKE_UNIT_KEY
,ISNULL(PED.ES_EMPLOYER_KEY, 0) AS ES_PLCMT_EMPLOYER_KEY
,ISNULL(PD.ES_PARTICIPANT_KEY, 0) AS ES_CREATOR_USERS_KEY
,CONVERT(VARCHAR(8), CONVERT(DATE,P.PLACED_DATE), 112) AS PLACED_DATE_KEY
,CONVERT(VARCHAR(8), CONVERT(DATE,P.CREATED_DATE), 112) AS PLCMT_RECORDED_DATE_KEY
,CONVERT(DATETIME, CONVERT(DATE,GETDATE())) AS LOAD_DATE
,1 AS PLCMT_CNT
,CASE WHEN P.PLACEMENT_TYPE = 0 THEN 1 ELSE 0 END AS OBTAIN_JOB_CNT
,CASE WHEN P.PLACEMENT_TYPE = 2 THEN 1 ELSE 0 END AS ENROLL_SBA_CNT
,CASE WHEN P.PLACEMENT_TYPE = 3 THEN 1 ELSE 0 END AS STARTED_BUSINESS_CNT
,CASE WHEN P.PLACEMENT_TYPE = 1 THEN 1 ELSE 0 END AS BEGIN_EDU_TRAINING_CNT
,U.MEMBER_1_0_FLAG AS MEMBER_CNT
,CASE WHEN P.DI_FUNDED = 'Y' THEN 1 ELSE 0 END AS DI_FUNDED_CNT
,ISNULL(DTP.DAYS_TO_PLCMT, PF.DAYS_TO_PLCMT) AS DAYS_TO_PLCMT
,ISNULL(LD.LOCAL_COUNCIL_KEY, isnull(OVERRIDE_LC.Local_Council_Key, 1)) AS LOCAL_COUNCIL_KEY
FROM DSS_ERS_STAGE.ES_W_PLCMT_HIST P
LEFT JOIN DSS_ERS_STAGE.ES_PARTICIPANT_DIM U ON (P.CANDIDATE_ID =
U.CANDIDATE_ID)
LEFT JOIN DSS_ERS_STAGE.ES_W_USER WU ON (U.USER_ID = WU.USER_ID)
LEFT JOIN DSS_ERS_STAGE.ES_ORG_DIM O ON (WU.HOME_UNIT_NUMBER =
O.UNIT_NUMBER AND O.ORG_TYPE_ID IN (7,8) AND O.ORG_STATUS_CODE = 1)
LEFT JOIN DSS_ERS_STAGE.ES_ORG_DIM STK ON (O.STK_DIST_ORG_ID = STK.ORG_ID
AND STK.ORG_TYPE_ID IN (5,6) AND STK.ORG_STATUS_CODE = 1)
LEFT JOIN DSS_ERS_STAGE.ES_ORG_DIM CENTER ON (O.RSC_CNTR_ORG_ID =
CENTER.ORG_ID AND (CENTER.ORG_TYPE_ID IN (60,61)) AND
(CENTER.ORG_STATUS_CODE =1))
LEFT JOIN DSS_ERS_STAGE.ES_PARTICIPANT_ATTR_DIM A ON (A.ID_AS_VARCHAR =
(ISNULL(U.PROF_VISIBLE_1_0_FLAG, '') +
ISNULL(U.PROF_STAFF_1_0_FLAG, '') +
ISNULL(U.DI_ASSOCIATE_1_0_FLAG, '') +
ISNULL(U.PEF_STUDENT_1_0_FLAG, '') +
ISNULL(0, '') +
ISNULL(U.BISHOP_REPORT_1_0_FLAG, '') +
ISNULL(U.PROFILE_ACTIVE_1_0_FLAG, '') +
ISNULL(U.MEMBER_1_0_FLAG, '') +
ISNULL(U.ACCELERATED_1_0_FLAG, '') +
ISNULL(CASE WHEN P.DI_FUNDED = 'Y' THEN
1 ELSE 0 END, '')))
LEFT JOIN DSS_ERS_STAGE.ES_PLCMT_EMPLOYER_DIM PED ON
(P.PLACEMENT_HISTORY_ID = PED.CAND_HIST_PLCMT_ID)
LEFT JOIN DSS_ERS_STAGE.ES_PARTICIPANT_DIM PD ON (P.CREATED_BY_USER =
PD.USER_ID)
LEFT JOIN DSS_ERS_STAGE.ES_W_DTP_MAPPING_SS DTP ON (P.PLACEMENT_HISTORY_ID =
DTP.PLACEMENT_HISTORY_ID)
LEFT JOIN DSS_ERS_STAGE.ES_PLACEMENT_FACT PF ON (P.PLACEMENT_HISTORY_ID =
PF.DD_PLCMT_HIST_ID)
LEFT JOIN DSS_ERS_STAGE.ES_LOCAL_COUNCIL_DIM LD ON (P.LOCAL_COUNCIL =
LD.LOCAL_COUNCIL_ID)
LEFT JOIN DSS_ERS_STAGE.ES_LOCAL_COUNCIL_DIM OVERRIDE_LC ON
(STK.LOCAL_COUNCIL = OVERRIDE_LC.LOCAL_COUNCIL_NAME)
--WHERE P.PLACEMENT_HISTORY_ID = 1215
GROUP BY
P.PLACEMENT_HISTORY_ID
,U.ES_PARTICIPANT_KEY
,A.ES_PARTICIPANT_ATTR_KEY
,CENTER.ES_ORG_KEY
,O.ES_ORG_KEY
,STK.ES_ORG_KEY
,CONVERT(VARCHAR(8), CONVERT(DATE,P.PLACED_DATE), 112)
,CONVERT(VARCHAR(8), CONVERT(DATE,P.CREATED_DATE), 112)
,CONVERT(DATETIME, CONVERT(DATE,GETDATE()))
,CASE WHEN P.PLACEMENT_TYPE = 0 THEN 1 ELSE 0 END
,CASE WHEN P.PLACEMENT_TYPE = 2 THEN 1 ELSE 0 END
,CASE WHEN P.PLACEMENT_TYPE = 3 THEN 1 ELSE 0 END
,CASE WHEN P.PLACEMENT_TYPE = 1 THEN 1 ELSE 0 END
,U.MEMBER_1_0_FLAG
,CASE WHEN P.DI_FUNDED = 'Y' THEN 1 ELSE 0 END
,PED.ES_EMPLOYER_KEY
,PD.ES_PARTICIPANT_KEY
,ISNULL(DTP.DAYS_TO_PLCMT, PF.DAYS_TO_PLCMT)
,ISNULL(LD.LOCAL_COUNCIL_KEY, isnull(OVERRIDE_LC.Local_Council_Key, 1))
I'm getting this error in SQL Server. It's fairly ambiguous. The resources I've found on the web haven't helped much in understanding what the issue is here.
Msg 164, Level 15, State 1, Line 55
Each GROUP BY expression must contain at least one column that is not an
outer reference.
*I'm adding this sentence because stackoverflow is telling me that my post is mostly code and that I need more details......

You get this error when you have a constant as a key in the GROUP BY. For some reason, that bothers SQL Server.
In your case, the "constant" appears to be:
CONVERT(DATETIME, CONVERT(DATE, GETDATE()))
Simply remove this from the GROUP BY keys.
(And, just for the record, each reference to GETDATE() is evaluated once per query, so it is a "constant" for this purpose.)

Related

The SQL Server query is taking too long to load the data

The below query is actually a view which is being used to display the cash payment report. But it is taking too much of time to load the data
SELECT
Billing_AccountPaymentDate.DueDate,
SUM(Billing_AccountCharge.NetAmount) AS NetCharges,
ISNULL(SUM(AccountChargePayment.SchoolPayments + AccountChargePayment.SchoolRemittances + AccountChargePayment.SchoolRemittancesPending), 0) / SUM(Billing_AccountCharge.NetAmount) AS PercentCollected,
SUM(Billing_AccountCharge.NetAmount - ISNULL(AccountChargePayment.SchoolPayments + AccountChargePayment.SchoolRemittances + AccountChargePayment.SchoolRemittancesPending, 0)) AS RemainingBalance,
Billing_AccountPaymentDate.RemittanceEffectiveDate,
Billing_Account.SchoolId,
ISNULL(SUM(AccountChargePayment.SchoolPayments), 0) AS SchoolPayments,
ISNULL(SUM(AccountChargePayment.SchoolRemittances), 0) AS SchoolRemittances,
ISNULL(SUM(AccountChargePayment.SchoolRemittancesPending), 0) AS SchoolRemittancesPending,
Billing_Account.SchoolYearId,
ISNULL(SUM(AccountChargePayment.SchoolPayments + AccountChargePayment.SchoolRemittances), 0) AS TotalReceipts
FROM
Billing_AccountCharge
INNER JOIN
Billing_AccountInvoice ON
Billing_AccountInvoice.AccountInvoiceId = Billing_AccountCharge.AccountInvoiceId
INNER JOIN
Billing_Account ON
Billing_Account.AccountId = Billing_AccountInvoice.AccountId
INNER JOIN
Billing_PaymentMethod ON
Billing_PaymentMethod.PaymentMethodId = CASE WHEN Billing_AccountInvoice.AutomaticPaymentEligible = 1 THEN Billing_Account.PaymentMethodId ELSE 3 END -- Send Statements
INNER JOIN
Billing_AccountPaymentDate ON
Billing_AccountPaymentDate.AccountPaymentMethodId = Billing_PaymentMethod.AnticipatedAccountPaymentMethodId AND
Billing_AccountPaymentDate.DueDate = Billing_AccountInvoice.DueDate AND
Billing_AccountPaymentDate.HoldForFee = Billing_Account.HoldPaymentForFee
INNER JOIN
Billing_ChargeItem ON
Billing_ChargeItem.ChargeItemId = Billing_AccountCharge.ChargeItemId
LEFT OUTER JOIN
(
SELECT
Billing_AccountChargePayment.AccountChargeId,
SUM(CASE WHEN Billing_AccountPayment.AccountPaymentTypeId = 9 THEN Billing_AccountChargePayment.Amount ELSE 0 END) AS SchoolPayments,
SUM(CASE WHEN Billing_AccountChargePayment.SchoolRemittanceId IS NOT NULL THEN Billing_AccountChargePayment.Amount ELSE 0 END) AS SchoolRemittances,
SUM(CASE WHEN Billing_AccountChargePayment.SchoolRemittanceId IS NULL AND Billing_AccountPayment.AccountPaymentTypeId <> 9 THEN Billing_AccountChargePayment.Amount ELSE 0 END) AS SchoolRemittancesPending
FROM
Billing_AccountChargePayment
INNER JOIN
Billing_AccountPayment ON
Billing_AccountPayment.AccountPaymentId = Billing_AccountChargePayment.AccountPaymentId
GROUP BY
Billing_AccountChargePayment.AccountChargeId
) AccountChargePayment ON
AccountChargePayment.AccountChargeId = Billing_AccountCharge.AccountChargeId
WHERE
Billing_AccountInvoice.AccountInvoiceStatusId <> 4 AND -- Voided
Billing_ChargeItem.RemitToSchool = 1
AND Billing_Account.[SchoolId] = 6 --hard code in a school with data
AND Billing_Account.[SchoolYearId] = 12 --hard code in a school year with data
GROUP BY
Billing_AccountPaymentDate.DueDate,
Billing_AccountPaymentDate.RemittanceEffectiveDate,
Billing_Account.SchoolId,
Billing_Account.SchoolYearId
HAVING
SUM(Billing_AccountCharge.NetAmount) <> 0
order by Billing_AccountPaymentDate.DueDate ASC
It looks like the inner query in the left join is taking too much of time, both the tables already have non clustered index, I tried taking those tables outside but the data is not accurate
Use CTE instead of subquery and do all calculation there instead of in Left outer join. Moreover, use with(nolock) whenever you fetch data. Still your query is taking much more time then You should implement proper indexing.
WITH PaymentData AS (
SELECT
acp.AccountChargeId,
SUM(
CASE
WHEN ap.AccountPaymentTypeId = 9 THEN acp.Amount
ELSE 0
END
) AS SchoolPayments,
SUM(
CASE
WHEN acp.SchoolRemittanceId IS NOT NULL THEN acp.Amount
ELSE 0
END
) AS SchoolRemittances,
SUM(
CASE
WHEN acp.SchoolRemittanceId IS NULL AND ap.AccountPaymentTypeId <> 9 THEN acp.Amount
ELSE 0
END
) AS SchoolRemittancesPending
FROM
Billing_AccountChargePayment acp WITH(NOLOCK)
INNER JOIN Billing_AccountPayment ap WITH(NOLOCK) ON acp.AccountPaymentId = ap.AccountPaymentId
GROUP BY
acp.AccountChargeId
)
SELECT
apd.DueDate,
SUM(ac.NetAmount) AS NetCharges,
COALESCE(
SUM(pd.SchoolPayments + pd.SchoolRemittances + pd.SchoolRemittancesPending),
0
) / SUM(ac.NetAmount) AS PercentCollected,
SUM(ac.NetAmount - COALESCE(pd.SchoolPayments, 0) - COALESCE(pd.SchoolRemittances, 0) - COALESCE(pd.SchoolRemittancesPending, 0)) AS RemainingBalance,
apd.RemittanceEffectiveDate,
a.SchoolId,
COALESCE(SUM(pd.SchoolPayments), 0) AS SchoolPayments,
COALESCE(SUM(pd.SchoolRemittances), 0) AS SchoolRemittances,
COALESCE(SUM(pd.SchoolRemittancesPending), 0) AS SchoolRemittancesPending,
a.SchoolYearId,
COALESCE(SUM(pd.SchoolPayments + pd.SchoolRemittances), 0) AS TotalReceipts
FROM
Billing_AccountCharge ac WITH(NOLOCK)
INNER JOIN Billing_AccountInvoice ai WITH(NOLOCK) ON ac.AccountInvoiceId = ai.AccountInvoiceId
INNER JOIN Billing_Account a WITH(NOLOCK) ON ai.AccountId = a.AccountId
INNER JOIN Billing_PaymentMethod pm WITH(NOLOCK) ON pm.PaymentMethodId = CASE
WHEN ai.AutomaticPaymentEligible = 1 THEN a.PaymentMethodId
ELSE 3
END
INNER JOIN Billing_AccountPaymentDate apd WITH(NOLOCK) ON
apd.AccountPaymentMethodId = pm.AnticipatedAccountPaymentMethodId AND
apd.DueDate = ai.DueDate AND
apd.HoldForFee = a.HoldPaymentForFee
INNER JOIN Billing_ChargeItem ci WITH(NOLOCK) ON ac.ChargeItemId = ci.ChargeItemId
LEFT OUTER JOIN PaymentData pd WITH(NOLOCK) ON ac.AccountChargeId = pd.AccountChargeId
WHERE
ai.AccountInvoiceStatusId <> 4 AND
ci.RemitToSchool = 1 AND
a.SchoolId = 6 AND
a.SchoolYearId = 12
GROUP BY
apd.DueDate,
apd.RemittanceEffectiveDate,
a.SchoolId,
a.SchoolYearId
HAVING
SUM(ac.NetAmount) <> 0
ORDER BY
apd.DueDate ASC;

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= orwhen the subquery is used as an expression

I am having this error message. I have tried many other ways but can't resolve the issue.
I would be really grateful if someone could look at this :
;WITH progression
AS
(
SELECT
w.CustomerID,
CASE WHEN SUM(CASE WHEN w.workflowoutcomeid = 8 THEN 1 ELSE 0 END) > 0 THEN 'Yes' ELSE 'No' END AS [PG01],
CASE WHEN SUM(CASE WHEN w.workflowoutcomeid = 11 THEN 1 ELSE 0 END) > 0 THEN 'Yes' ELSE 'No' END AS [PG03],
CASE WHEN SUM(CASE WHEN w.workflowoutcomeid = 14 THEN 1 ELSE 0 END) > 0 THEN 'Yes' ELSE 'No' END AS [PG04],
CASE WHEN SUM(CASE WHEN w.workflowoutcomeid = 17 THEN 1 ELSE 0 END) > 0 THEN 'Yes' ELSE 'No' END AS [PG05],
CASE WHEN SUM(CASE WHEN w.workflowoutcomeid = 9 THEN 1 ELSE 0 END) > 0 THEN 'Yes' ELSE 'No' END AS [in_work_review]
FROM
ABC.dbo.tblWorkflow w
WHERE
w.Deleted IS NULL
AND
w.workflowqueueid = 4
AND
w.workflowoutcomeid IN (8, 11, 14, 17, 9)
GROUP BY
w.CustomerID
),
contact_data
AS
(
SELECT
CustomerID, [Email], [Mobile], [Home]
FROM
(
SELECT
CustomerID,
CASE
WHEN ContactTypeID = 1 THEN 'Home'
WHEN ContactTypeID = 2 THEN 'Mobile'
WHEN ContactTypeID = 5 THEN 'Email'
END AS ContactTypeDescription,
ContactValue
FROM ABC.dbo.tblCustomerContact
WHERE ContactTypeID IN (1,2,5)
) base
PIVOT
(
MAX(ContactValue) FOR ContactTypeDescription IN ([Home],[Mobile],[Email])
) pvt
),
appointment
AS
(
SELECT
n.[Key] AS CustomerID,
MAX(CASE WHEN n.AppointmentStatusID IN (2,4) THEN n.ActionDate ELSE NULL END) AS [Last_Completed_Attended_Appointment],
MAX(CASE WHEN n.AppointmentStatusID = 1 THEN n.ActionDate ELSE NULL END) AS [Next Pending Appointment]
FROM ABC.dbo.tblNote n
WHERE n.AppointmentTypeID = 6 AND n.AppointmentStatusID IN (1,2,4)
GROUP BY n.[Key]
)
SELECT
m.Firstname + ' ' + m.Lastname AS [Manager],
u.Firstname + ' ' + u.Lastname AS [Adviser],
c.CustomerID,
c.GivenName + ' ' + c.FamilyName AS [Customer Name],
g.Gender,
e.EthnicityName AS Ethnicity,
com.CompanyName,
NULL AS DeliverySite,
d.[Name] AS District,
css.ServiceStatus,
contact_data.Email,
uad.Line1 AS AddressLine1,
uad.Line2 AS AddressLine2,
uad.Line3 AS AddressLine3,
uad.Postcode,
uad.AlternativePostcode,
uad.Town,
ISNULL(contact_data.mobile, contact_data.home) AS Phone,
c.StartDate,
(SELECT MIN(wh.MGCReviewerModifiedDate) AS [ST01_Approved_Date]
FROM ABC.dbo.tblWorkflow w
INNER JOIN ABC.dbo.tblWorkflowHistory wh
ON w.WorkflowID = wh.WorkflowID
WHERE wh.WorkflowQueueID = 4 AND wh.MGCReviewerModifiedDate IS NOT NULL
AND wh.Deleted IS NULL AND w.WorkflowOutcomeID = 1 AND w.WorkflowQueueID = 4
AND w.Deleted IS NULL AND w.CustomerID = c.CustomerID
GROUP BY w.WorkflowID, w.CustomerID) AS ST01_Approved_Date,
qual.LearningAimTitle,
qual.LearningAimCompletionStatus,
qual.LearningAimOutcomeStatus,
mwp.WorkExperienceTitle ,
mwp.WorkExperienceStartDate,
mwp.WorkExperienceEndDate,
mwp.learningaimcompletionstatus as [Work_Ex_CompletionStatus],
mwp.learningaimoutcomestatus as [Work_Ex_OutcomeStatus],
p.PG01 AS [PG01_Start(Job Start Approved/Claimed ?)],
p.in_work_review AS [PG01_In_work_review(Job Outcome Approved/Claimed ?)],
p.PG03 AS [PG03 – Education Approved / Claimed?],
p.PG04 AS [PG04 – Apprenticeship Approved / Claimed?],
p.PG05 AS [PG05– Apprenticeship Approved / Claimed?],
a.Last_Completed_Attended_Appointment,
a.[Next Pending Appointment],
FLOOR(DATEDIFF(day, c.DateOfBirth, GETDATE()) / 365.25) as CustomerAge
FROM ABC.dbo.tblCustomer c
LEFT JOIN ABC.dbo.tblUser u ON c.OwnerID = u.UserID
LEFT JOIN ABC.dbo.tblUser m ON u.ManagerID = m.UserID
LEFT JOIN ABC.dbo.tlkpGender g ON c.GenderID = g.GenderID
LEFT JOIN ABC.dbo.tlkpEthnicity e ON c.EthnicityID = e.EthnicityID
LEFT JOIN ABC.dbo.tblCompany com ON c.CompanyId = com.[CompanyID]
LEFT JOIN ABC.dbo.tblCustomerAddress cad ON c.CustomerID = cad.CustomerID AND cad.EffectiveTo IS NULL
LEFT JOIN ABC.dbo.tblUKAddress uad ON uad.UKaddressID = cad.UKaddressID
LEFT JOIN PostcodeESyNCS.dbo.tblPostcode po ON uad.Postcode = po.Postcode
LEFT JOIN PostcodeESyNCS.dbo.tlkpDistrict d ON po.DistrictId = d.DistrictId
LEFT JOIN ABC.dbo.tlkpCustomerServiceStatus css ON c.CustomerServiceStatusID = css.CustomerServiceStatusID
LEFT JOIN progression p ON c.CustomerID = p.CustomerID
LEFT JOIN contact_data ON c.CustomerID = contact_data.CustomerID
OUTER APPLY
(
SELECT TOP 1
l.learningaimid,
aim.LearningAimTitle,
aim.isfullqualification,
st.LearningAimCompletionStatus,
aos.LearningAimOutcomeStatus
FROM ABC.dbo.tbllearning l
LEFT JOIN ABC.dbo.tlkplearningaim aim on aim.learningaimid = l.learningaimid
LEFT JOIN ABC.dbo.tlkplearningaimcompletionstatus st on st.learningaimcompletionstatusid = l.learningaimcompletionstatusid
LEFT JOIN ABC.dbo.tlkpLearningAimOutcomeStatus aos on aos.learningaimoutcomestatusid = l.learningaimoutcomestatusid
WHERE aim.learningaimtypeid = 1 AND l.customerid = c.customerid
ORDER BY l.StartDate DESC
) qual
OUTER APPLY
(
SELECT TOP 1
l.learningaimid,
REPLACE(aim.LearningAimTitle,',',' ') as WorkExperienceTitle,
aim.isfullqualification,
st.LearningAimCompletionStatus,
outcome.LearningAimOutcomeStatus,
l.StartDate as WorkExperienceStartDate,
l.ActualEndDate as WorkExperienceEndDate
FROM ABC.dbo.tbllearning l
LEFT JOIN ABC.dbo.tlkplearningaim aim ON aim.learningaimid=l.learningaimid
LEFT JOIN ABC.dbo.tlkplearningaimcompletionstatus st ON st.learningaimcompletionstatusid=l.learningaimcompletionstatusid
LEFT JOIN ABC.dbo.tlkpLearningAimOutcomeStatus outcome ON outcome.learningaimoutcomestatusid= l.learningaimoutcomestatusid
WHERE aim.LearningAimID IN (SELECT la.LearningAimID
FROM ABC.dbo.tlkpLearningAim la
WHERE la.LearningAimTypeID = 2
and la.LearningAimTitle like '%Work%')
AND l.customerid = c.customerid
ORDER BY StartDate DESC
) AS mwp
LEFT JOIN appointment a ON c.CustomerID = a.CustomerID
WHERE
c.Deleted IS NULL
I am getting the following error:
Msg 512, Level 16, State 1, Line 2
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Warning: Null value is eliminated by an aggregate or other SET operation.
The only place where I see that this could be happening is the definition of ST01_Approved_Date:
(SELECT MIN(wh.MGCReviewerModifiedDate) AS [ST01_Approved_Date]
FROM ABC.dbo.tblWorkflow w JOIN
ABC.dbo.tblWorkflowHistory wh
ON w.WorkflowID = wh.WorkflowID
WHERE wh.WorkflowQueueID = 4 AND wh.MGCReviewerModifiedDate IS NOT NULL AND
wh.Deleted IS NULL AND w.WorkflowOutcomeID = 1 AND w.WorkflowQueueID = 4 AND
w.Deleted IS NULL AND w.CustomerID = c.CustomerID
GROUP BY w.WorkflowID, w.CustomerID
) AS ST01_Approved_Date,
A correlated subquery should not contain GROUP By for exactly this reason. I don't know what the logic would be, but there should probably be a condition on w.WorkFlowId to the outer query, something like:
(SELECT MIN(wh.MGCReviewerModifiedDate) AS [ST01_Approved_Date]
FROM ABC.dbo.tblWorkflow w JOIN
ABC.dbo.tblWorkflowHistory wh
ON w.WorkflowID = wh.WorkflowID
WHERE wh.WorkflowQueueID = 4 AND wh.MGCReviewerModifiedDate IS NOT NULL AND
wh.Deleted IS NULL AND w.WorkflowOutcomeID = 1 AND w.WorkflowQueueID = 4 AND
w.Deleted IS NULL AND w.CustomerID = c.CustomerID AND
w.workflowID = <outer query reference>.WorkflowId
) AS ST01_Approved_Date,

Why is this sql query running so slowly? Large table with detailed string filter

The query below is running on a ~20000 row table. Each customer has 1-3 customer contacts. This particular query is taking more than 6 seconds to run despite only returning 11 rows. Which part is killing it?
SELECT C.Id,
CASE
WHEN CT.Name = 'Residential' THEN ISNULL(CC.FirstName, '') + ' ' + ISNULL(CC.LastName, '')
ELSE C.CompanyName
END AS FullName,
C.CustomerTypeId,
CT.Name,
ISNULL(CC.PhoneNumber, '') AS PhoneNumber,
A.City,
S.Name,
A.Street,
A.Zip,
C.TaxExempt,
C.Active,
ISNULL(C.CompanyName, '') AS CopmanyName,
ISNULL(CC.FirstName, '') AS CustomerContactFirstName,
ISNULL(CC.LastName, '') AS CustomerContactLastName
FROM [dbo].[Customer] C
JOIN Address A ON A.Id = C.AddressId
JOIN State S ON A.StateId = S.Id
JOIN CustomerType CT ON CT.Id = C.CustomerTypeId
LEFT OUTER JOIN CustomerContact CC ON CC.CustomerId = C.Id
AND CC.Active = 1
AND CC.[Primary] = 1
WHERE (0 = 1
OR C.Active = 1)
AND
(CT.Name +'|'+ ISNULL(CC.PhoneNumber,'') +'|'+ S.Name +'|'+ LTRIM(A.Street) + '|' + LTRIM(A.Zip)
+ CASE WHEN CT.Name = 'residential' THEN LTRIM(RTRIM(ISNULL(CC.FirstName, ''))) + ' ' + LTRIM(RTRIM(ISNULL(CC.LastName, ''))) ELSE '' END
+ CASE WHEN CT.Name != 'residential' THEN LTRIM(C.CompanyName) ELSE '' END
+ CASE WHEN C.TaxExempt = 1 THEN 'tax Exempt' ELSE '' END
+ CASE WHEN C.TaxExempt = 0 THEN 'taxable' ELSE '' END
+ CASE WHEN C.Active = 1 THEN 'active' ELSE '' END
+ CASE WHEN C.Active = 0 THEN 'not active' ELSE '' END
)
LIKE '%' + CASE WHEN lower('jake') = 'null' THEN '' ELSE lower('jake') END + '%'
ORDER BY FullName
OFFSET 0 ROWS -- skip rows
FETCH NEXT 150 ROWS ONLY; -- take rows
Basically like statement always costing time
in below query within case statement whichever record matching case condition it will return first so no need to search for other conditions
Hope so you got your answer
SELECT C.Id,
CASE
WHEN CT.Name = 'Residential' THEN ISNULL(CC.FirstName, '') + ' ' + ISNULL(CC.LastName, '')
ELSE C.CompanyName
END AS FullName,
C.CustomerTypeId,
CT.Name,
ISNULL(CC.PhoneNumber, '') AS PhoneNumber,
A.City,
S.Name,
A.Street,
A.Zip,
C.TaxExempt,
C.Active,
ISNULL(C.CompanyName, '') AS CopmanyName,
ISNULL(CC.FirstName, '') AS CustomerContactFirstName,
ISNULL(CC.LastName, '') AS CustomerContactLastName
FROM [dbo].[Customer] C
JOIN Address A ON A.Id = C.AddressId
JOIN State S ON A.StateId = S.Id
JOIN CustomerType CT ON CT.Id = C.CustomerTypeId
LEFT OUTER JOIN CustomerContact CC ON CC.CustomerId = C.Id
AND CC.Active = 1
AND CC.[Primary] = 1
WHERE (#VARIABLE1 = 1
OR C.Active = 1)
AND CASE WHEN isnull(#variable,'') !='' THEN
CASE WHEN Lower(C.CompanyName) like '%' + lower(#variable)+'%' THEN 1
WHEN Lower(CC.FirstName) like '%' + lower(#variable)+'%' THEN 1
WHEN Lower(CC.LastName) like '%' + lower(#variable)+'%' THEN 1
ELSE 0 END
ELSE 0 END =1
ORDER BY FullName
OFFSET 0 ROWS -- skip rows
FETCH NEXT 150 ROWS ONLY; -- take rows
You should look at the execution plan. Your request is not sargeable, which means you don't use indexes correctly.
First, don't use functions in the where clause (case, lower, isnull...). You should have calculated columns with indexes on them instead if you can't already insert good datas into the columns.
Try avoiding like '%xxxxxx'. Non sargeable if the percent isn't at the end of the string.
Avoid using left join. Sometimes it is better to do your request and store results into a temporary table and then use a left join on it.
Finally, you should try some indexes with included columns.

SQL Server - 2008 : Nested Select, need improve execution faster?

Here the problem:
First I have a nested query, for which I need to improve the execution time and make it faster. Imagine 47 seconds at first time and second time was 46 / 45 second. Second was running by cache (the second execution always faster than first time but not this).
Second that query uses SUM, CAST, CASE in each sub select. Can't dodge that
Third I read some another solution from internet using OPTION (FAST 500).
Here the example :
SELECT [cutomerSection],
SUM(DEBIT) AS DEBIT,
SUM(CREDIT) AS CREDIT,
SUM([OTHERS]) AS 'OTHERS'
FROM
(-- SECTOR A
SELECT cb.paymentGrp AS 'cutomerSection',
CASE
WHEN j.paymentStat = 'DEBIT' THEN SUM(CAST(ISNULL(isnull(qty, 1)*(100-disc)*d.adm/100, 0) AS INT)) + SUM(CAST(ISNULL(isnull(qty, 1)*(100-disc)*(d.fee-d.adm)/100, 0) AS INT))
ELSE 0
END AS 'DEBIT',
CASE
WHEN j.paymentStat = 'CREDIT' THEN SUM(CAST(ISNULL(isnull(qty, 1)*(100-disc)*d.adm/100, 0) AS INT)) + SUM(CAST(ISNULL(isnull(qty, 1)*(100-disc)*(d.fee-d.adm)/100, 0) AS INT))
ELSE 0
END AS 'CREDIT',
CASE
WHEN (j.paymentStat = ''
OR j.paymentStat IS NULL) THEN SUM(CAST(ISNULL(isnull(qty, 1)*(100-disc)*d.adm/100, 0) AS INT)) + SUM(CAST(ISNULL(isnull(qty, 1)*(100-disc)*(d.fee-d.adm)/100, 0) AS INT))
ELSE 0
END AS 'OTHERS'
FROM tbactDetail d WITH(NOLOCK)
LEFT JOIN tbsectorSection j WITH(NOLOCK) ON d.tranCode = j.tranCode
LEFT JOIN tbact t ON (d.actCode=t.actCode
AND t.sectorCode = j.sectorCode)
LEFT JOIN tbCustomer c WITH(NOLOCK) ON c.custCode=j.custCode
LEFT JOIN tbfrontDesk a WITH(NOLOCK) ON a.struckNo=j.struk
LEFT JOIN tbpaymentList cb WITH(NOLOCK) ON cb.paymentK = a.paymentK
LEFT JOIN tbleading dc ON dc.leadCode = j.leadCode
LEFT JOIN tbsector p ON j.sectorCode = p.sectorCode
WHERE (j.deleted IS NULL
OR j.deleted = 0)
AND a.status = 'FINISH'
AND (j.tranDate BETWEEN '2018-11-01 00:00:00' AND '2018-11-01 23:59:59')
GROUP BY cb.paymentGrp,
j.paymentStat
UNION ALL -- SECTOR PARK
SELECT cb.paymentGrp AS 'cutomerSection',
CASE
WHEN t.paymentStat = 'DEBIT' THEN SUM(CAST(isnull(d.rate*d.qty*(100-disc)/100, 0) AS INT))
ELSE 0
END AS 'DEBIT',
CASE
WHEN t.paymentStat = 'CREDIT' THEN SUM(CAST(isnull(d.rate*d.qty*(100-disc)/100, 0) AS INT))
ELSE 0
END AS 'CREDIT',
CASE
WHEN (t.paymentStat = ''
OR t.paymentStat IS NULL) THEN SUM(CAST(isnull(d.rate*d.qty*(100-disc)/100, 0) AS INT))
ELSE 0
END AS 'OTHERS'
FROM tbparkDetail d
LEFT JOIN tbTranPark t ON d.tranCode = t.tranCode
JOIN tbsectorSection j ON t.strukPoli = j.struk
LEFT JOIN tbCustomer c WITH(NOLOCK) ON c.custCode=j.custCode
LEFT JOIN tbfrontDesk a WITH(NOLOCK) ON a.struckNo=j.struk
JOIN tbpaymentList cb ON a.paymentK = cb.paymentK
LEFT JOIN tbleading dc ON dc.leadCode=j.leadCode
LEFT JOIN tbsector p ON j.sectorCode=p.sectorCode
WHERE (j.deleted IS NULL
OR j.deleted=0)
AND (t.strukPoli IS NOT NULL
OR t.strukPoli <> ''
OR t.strukPoli <> '--')
AND a.status = 'FINISH'
AND (j.tranDate BETWEEN '2018-11-01 00:00:00' AND '2018-11-01 23:59:59')
GROUP BY cb.paymentGrp,
t.paymentStat
UNION ALL -- SECTOR FRONT
SELECT cb.paymentGrp AS 'cutomerSection',
CASE
WHEN t.paymentStat = 'DEBIT' THEN SUM(CAST(isnull(d.rate*(100-disc)/100, 0) AS INT))
ELSE 0
END AS 'DEBIT',
CASE
WHEN t.paymentStat = 'CREDIT' THEN SUM(CAST(isnull(d.rate*(100-disc)/100, 0) AS INT))
ELSE 0
END AS 'CREDIT',
CASE
WHEN (t.paymentStat = ''
OR t.paymentStat IS NULL) THEN SUM(CAST(isnull(d.rate*(100-disc)/100, 0) AS INT))
ELSE 0
END AS 'OTHERS'
FROM tbDetailRadioterapi d
LEFT JOIN tbtranFront t ON d.tranCode = t.tranCode
LEFT JOIN tbsectorSection j ON t.strukPoli = j.struk
LEFT JOIN tbCustomer c WITH(NOLOCK) ON c.custCode=j.custCode
LEFT JOIN tbfrontDesk a WITH(NOLOCK) ON a.struckNo = j.struk
LEFT JOIN tbpaymentList cb ON a.paymentK = cb.paymentK
LEFT JOIN tbleading dc ON dc.leadCode=j.leadCode
LEFT JOIN tbsector p ON j.sectorCode=p.sectorCode
WHERE (t.deleted IS NULL
OR t.deleted=0)
AND (strukPoli IS NOT NULL
OR strukPoli <>''
OR strukPoli <>'--')
AND a.status='FINISH'
AND (j.tranDate BETWEEN '2018-11-01 00:00:00' AND '2018-11-01 23:59:59')
GROUP BY cb.paymentGrp,
t.paymentStat) AS a
GROUP BY [cutomerSection]
Third using option (fast 500), I don't know why but always got error :
Incorect Syntax near OPTION
PS : Sorry for my bad English

How to replace any NULL values with an integer that might or could appear in the Foreign key columns

When I run the script, The 5 foreign keys such as ResourceKey, AusFunctionKey, IntFunctionKey, RegionViewKey and EntityKey from 5 dimension tables always have values. Because I set the 5 primary keys data type in each dimension tables as INT. However, when I link all dimensions into a fact table, there are "some" foreign keys that have NULL values.
How do I put a case when statement or anything that I could add to replace any NULL values with an integer such as "1"??
SELECT d.resourcekey,
CONVERT(INT, CONVERT(VARCHAR(8), Dateadd(dd, -Datepart(dw, Getdate()),
Getdate()
), 112)) AS TimeKey,
A.ausfunctionkey,
I.intfunctionkey,
o.regionviewkey,
E.entitykey AS EmployingEntityKey,
r.resourceid,
r.subsubfunctioncode,
r.sublocationcode,
r.site,
t.sitedesc,
Sum(t.itemvalue1) AS HoursOutstanding,
Sum(t.itemvalue1 * Isnull(CASE
WHEN t.itemvalue2 = 0 THEN r.costrateregoper
ELSE r.costrateintoper
END, 0)) AS OperCostOutstanding,
Sum(t.itemvalue1 * Isnull(CASE
WHEN t.itemvalue2 = 0 THEN
r.chargerateregoper
ELSE r.chargerateintoper
END, 0)) AS OperRevenueOutstanding,
Sum(t.itemvalue1 * Isnull(CASE
WHEN t.itemvalue2 = 0 THEN r.costratereghome
ELSE r.costrateinthome
END, 0)) AS HomeCostOutstanding,
Sum(t.itemvalue1 * Isnull(CASE
WHEN t.itemvalue2 = 0 THEN
r.chargeratereghome
ELSE r.chargerateinthome
END, 0)) AS HomeRevenueOutstanding,
r.homecurrcode,
Sum(t.itemvalue1 * Isnull(CASE
WHEN t.itemvalue2 = 0 THEN r.costrateregnat
ELSE r.costrateintnat
END, 0)) AS NatCostOutstanding,
Sum(t.itemvalue1 * Isnull(CASE
WHEN t.itemvalue2 = 0 THEN r.chargerateregnat
ELSE r.chargerateintnat
END, 0)) AS NatRevenueOutstanding,
r.natcurrcode
FROM ods_currentresource r
LEFT OUTER JOIN ods_staff_task t
ON R.resourceid = T.resourceid
LEFT OUTER JOIN dwresourcetask.dbo.dimresource D
ON T.resourceid = D.resourceid
LEFT OUTER JOIN dwresourcetask.dbo.dimaustralianfunction A
ON R.subsubfunctioncode = A.subsubfunctioncode
LEFT OUTER JOIN dwresourcetask.dbo.diminternationalfunction I
ON R.subsubfunctioncode = I.subsubfunctioncode
LEFT OUTER JOIN dwresourcetask.dbo.dimregion o
ON R.sublocationcode = o.sublocationcode
LEFT OUTER JOIN dwresourcetask.dbo.dimentity E
ON R.legalentity = E.entcode
WHERE r.resourcetypecode <> 'C'
AND t.sitedesc = r.resourcesite
AND t.tasktypeid IN ( 5, 6 ) --missing time
GROUP BY d.resourcekey,
A.ausfunctionkey,
I.intfunctionkey,
o.regionviewkey,
E.entitykey,
r.resourceid,
r.subsubfunctioncode,
r.sublocationcode,
r.site,
t.sitedesc,
t.resourceid,
r.homecurrcode,
r.natcurrcode
You could use ISNULL(A.ausfunctionkey, 1) as ausfunctionkey when querying. This will give you the appopriate value or if it is NULL, then the output will be 1
CASE
WHEN [myRow] IS NULL THEN 1234
END
Or (as somebody else said) use ISNULL
Example:
SELECT Description, ISNULL(MaxQty, 0.00) AS 'Max Quantity' FROM Sales.SpecialOffer;