Calculations in SQL and preventing Divide By Zero - sql

I am trying to rework a query that is based on cursors.
The query calculates certain stats based on multiple values. In the snippet below the first, second and third CASE works out the happiness of Unit1. Any of these fields are 0 (they can never be NULL) I will get a Divide by Zero error. I could just add 1 to each field (Unit2 + 1) / (Unit1 + 1) and that will stop the error. However, it seems like a bodge and it will potentially give the incorrect result. ie. Unit1 needs the same amount of Unit2 to keep them happy. If I have one Unit1 and no Unit2 this bodge will give 100% happy for that check. So my first problem is how do I prevent the divide by zero but not distort the results. Each CASE gives me a % happy
Select
CASE WHEN ((Unit2 / Unit1) * 100) > 100 Then 100 Else ((Unit2 / Unit1) * 100) END Unit1Happy1,
CASE WHEN ((Stock3 / (Unit1 * 2)) * 100) > 100 Then 100 Else ((Stock3 / (Unit1 * 2)) * 100) END Unit1Happy2,
CASE WHEN (((Drug3 + (Drug1 / 2)) / Unit1) * 100) > 100 Then 100 Else (((Drug3 + (Drug1 / 2)) / Unit1) * 100) END Unit1Happy3,
CASE WHEN (((Weapon6 + Weapon7 + Weapon8 + Weapon9) / Unit2) * 100) > 100 Then 100 ELSE (((Weapon6 + Weapon7 + Weapon8 + Weapon9) / Unit2) * 100) END Unit2Happ1,
CASE WHEN (((Stock2 + (Stock1 / 2)) / Unit2) * 100) > 100 Then 100 Else (((Stock2 + (Stock1 / 2)) / Unit2) * 100) END Unit2Happ2
FROM tblUserFiles
My next problem is that I need to take to lowest value for each UnitHappiness and store that value in the table. So in tblUserFiles are 5 fields Unit1Happ, Unit2Happ .... Unit5Happ. Looking at the above query if Unit1Happy1 is the lowest figure I store that figure into Unit1Happ, If Unit2Happy is the lowest I store that etc.
My record Identifier is UserId and I need to run this for a given UserId or for the whole table.
What I am basically asking is:
What is the best method to identify the lowest value of each Unit
calculation?
What is the best way to prevent the divide by zero
error?
Can I approach this problem in a better way?
Update
I am working through the suggestions posted in the answers below. As this is just a training exercise it may take a while. I do have a working query that gives the results I am looking for I am just not sure if the suggested answers would be more efficient.
Update tblUserFiles Set Unit1Happ = happyvals.Unit1Happiness, Unit2Happ = happyvals.Unit2Happiness, Unit3Happ = happyvals.Unit3Happiness, Unit4Happ = happyvals.Unit4Happiness, Unit5Happ = happyvals.Unit5Happiness FROM
(SELECT ch.UserId,
Case When ch.Unit1Happy1 < ch.Unit1Happy2 And ch.Unit1Happy1 < ch.Unit1Happy3 Then ch.Unit1Happy1
When ch.Unit1Happy2 < ch.Unit1Happy1 And ch.Unit1Happy2 < ch.Unit1Happy3 Then ch.Unit1Happy2
Else ch.Unit1Happy3
End As Unit1Happiness,
CASE WHEN ch.Unit2Happy1 > ch.Unit2Happy2 THEN ch.Unit2Happy1
ELSE ch.Unit2Happy2
END AS Unit2Happiness,
ch.Unit3Happy1 AS Unit3Happiness,
ch.Unit4Happy1 AS Unit4Happiness,
ch.Unit5Happy1 AS Unit5Happiness
FROM
(
Select
UserId,
CASE WHEN Unit2 = 0 OR Unit1 = 0 THEN 0
WHEN ((Unit2 / Unit1) * 100) > 100 Then 100
ELSE ((Unit2 / Unit1) * 100)
END Unit1Happy1,
CASE WHEN Stock3 = 0 OR Unit1 = 0 THEN 0
WHEN ((Stock3 / (Unit1 * 2)) * 100) > 100 THEN 100
ELSE ((Stock3 / (Unit1 * 2)) * 100)
END Unit1Happy2,
CASE WHEN Unit1 = 0 THEN 0
WHEN Drug3 = 0 AND Drug1 = 0 THEN 0
WHEN Drug1 = 0 THEN
CASE WHEN (Drug3 / Unit1) * 100 > 100 THEN 100
ELSE (Drug3 / Unit1) * 100
END
WHEN Drug3 = 0 THEN
CASE WHEN (Drug1 / 2) / Unit1 > 100 THEN 100
ELSE (Drug1 / 2) / Unit1
END
ELSE
CASE WHEN (((Drug3 + (Drug1 / 2)) / Unit1) * 100) > 100 THEN 100
ELSE (((Drug3 + (Drug1 / 2)) / Unit1) * 100)
END
END Unit1Happy3,
CASE WHEN Unit2 = 0 THEN 0
WHEN (Weapon6 + Weapon7 + Weapon8 + Weapon9) = 0 THEN 0
WHEN (((Weapon6 + Weapon7 + Weapon8 + Weapon9) / Unit2) * 100) > 100 THEN 100
ELSE (((Weapon6 + Weapon7 + Weapon8 + Weapon9) / Unit2) * 100)
END Unit2Happy1,
CASE WHEN Unit2 = 0 THEN 0
WHEN Stock1 = 0 AND Stock2 = 0 THEN 0
WHEN Stock1 = 0 THEN
CASE WHEN ((Stock2 / Unit2) * 100) > 100 THEN 100
ELSE ((Stock2 / Unit2) * 100)
END
WHEN Stock2 = 0 THEN
CASE WHEN (((Stock1 / 2) / Unit2) * 100) > 100 THEN 100
ELSE (((Stock1 / 2) / Unit2) * 100)
END
WHEN (((Stock2 + (Stock1 / 2)) / Unit2) * 100) > 100 THEN 100
ELSE (((Stock2 + (Stock1 / 2)) / Unit2) * 100)
END Unit2Happy2,
CASE WHEN Unit2 = 0 OR Unit3 = 0 THEN 0
WHEN ((Unit2 / Unit3) * 100) > 100 THEN 100
ELSE ((Unit2 / Unit3) * 100)
END Unit3Happy1,
CASE WHEN Unit2 = 0 OR Unit4 = 0 THEN 0
WHEN ((Unit2 / Unit4) * 100) > 100 THEN 100
ELSE ((Unit2 / Unit4) * 100)
END Unit4Happy1,
CASE WHEN Unit2 = 0 OR Unit5 = 0 THEN 0
WHEN ((Unit2 / Unit5) * 100) > 100 THEN 100
ELSE ((Unit2 / Unit5) * 100)
END Unit5Happy1
FROM tblUserFiles) ch) happyvals
Join tblUserFiles ON tblUserFiles.UserID = happyvals.UserID

put a nullif(Unit1, 0) around every divide by group ?

Something like this.
The idea is to wrap your division in a UDF (scalar user defined function)....and use the "Max(v)" trick.
The code below may not be perfect, I've supplying the idea.
Cursors are horrible performers, 99.9% of the time. Try to solve this without cursors.
/* or Create */
ALTER FUNCTION dbo.udfSafeDivision (#num float , #denom float)
RETURNS float
AS
BEGIN
declare #returnValue float
select #returnValue = 0
if(isnull(#denom,0) != 0)
BEGIN
select #returnValue = convert(float, convert(float, #num)/convert(float, #denom))
END
return #returnValue
END
GO
IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
drop table #TableOne
end
CREATE TABLE #TableOne
(
SurrogateKey int IDENTITY(1001, 1),
Unit1 int ,
Unit2 int ,
Stock1 int ,
Stock2 int ,
Stock3 int ,
Drug1 int ,
Drug3 int ,
Weapon6 int , Weapon7 int , Weapon8 int , Weapon9 int
)
Insert into #TableOne (Unit1, Unit2, Stock1, Stock2 , Stock3 , Drug1, Drug3 , Weapon6 , Weapon7 , Weapon8 , Weapon9)
select 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
UNION ALL select 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
UNION ALL select 1 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
UNION ALL select 1 , 2 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
UNION ALL select 1 , 2 , 3 , 4 , 0 , 0 , 0 , 0 , 0 , 0 , 0
UNION ALL select 1 , 2 , 3 , 4 , 5 , 0 , 0 , 0 , 0 , 0 , 0
UNION ALL select 1 , 2 , 3 , 4 , 5 , 6 , 0 , 0 , 0 , 0 , 0
UNION ALL select 1 , 2 , 3 , 4 , 5 , 6 , 7 , 0 , 0 , 0 , 0
UNION ALL select 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 0 , 0 , 0
UNION ALL select 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 , 0
UNION ALL select 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 0
UNION ALL select 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11
UNION ALL select 5 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
UNION ALL select 5 , 0 , 0 , 0 , 5 , 0 , 0 , 0 , 0 , 0 , 0
UNION ALL select 10 , 0 , 0 , 0 , 0 , 5 , 10 , 0 , 0 , 0 , 0
UNION ALL select 0 , 1 , 0 , 0 , 0 , 5 , 10 , 10 , 20 , 30 , 40
UNION ALL select 0 , 50 , 20 , 10 , 0 , 0 , 0 , 0 , 0 , 0 , 0
SELECT
(SELECT Max(v)
FROM (VALUES (Unit1Happy1), (Unit1Happy2), (Unit1Happy3), (Unit2Happ1), (Unit2Happ2)) AS value(v)) as [MaxValue]
, '--------' as Sep1
, derived1.*
FROM
(
Select
CASE WHEN ((dbo.udfSafeDivision(Unit2 , Unit1)) * 100) > 100 Then 100 Else (dbo.udfSafeDivision(Unit2 , Unit1) * 100) END Unit1Happy1,
CASE WHEN (dbo.udfSafeDivision(Stock3 , (Unit1 * 2)) * 100) > 100 Then 100 Else (dbo.udfSafeDivision(Stock3 , (Unit1 * 2)) * 100) END Unit1Happy2,
CASE WHEN (dbo.udfSafeDivision((Drug3 + (Drug1 / 2)) , Unit1) * 100) > 100 Then 100 Else (dbo.udfSafeDivision((Drug3 + (Drug1 / 2)) , Unit1) * 100) END Unit1Happy3,
CASE WHEN (dbo.udfSafeDivision((Weapon6 + Weapon7 + Weapon8 + Weapon9) , Unit2) * 100) > 100 Then 100 ELSE (dbo.udfSafeDivision((Weapon6 + Weapon7 + Weapon8 + Weapon9) , Unit2) * 100) END Unit2Happ1,
CASE WHEN (dbo.udfSafeDivision((Stock2 + (Stock1 / 2)) , Unit2) * 100) > 100 Then 100 Else (dbo.udfSafeDivision((Stock2 + (Stock1 / 2)) , Unit2) * 100) END Unit2Happ2
/* the below is to debug */
, '--' as Sep1
, Unit1, Unit2, Stock1, Stock2 , Stock3 , Drug1, Drug3 , Weapon6 , Weapon7 , Weapon8 , Weapon9
, dbo.udfSafeDivision(Unit2 , Unit1) as Div1
, dbo.udfSafeDivision(Stock3 , (Unit1 * 2)) as Div3
FROM #TableOne
) as derived1
IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
drop table #TableOne
end

Related

Two fast queries, slow when combined

I have this massive query that I am trying to add a left join to. The addition is commented out.
The main query runs < 4 sec, 32,000 rows.
The commented part runs < 1 sec, 51,000 rows.
But, when I combine them i.e join the second query, the whole thing runs in 15 sec.
There are already 2 massive joins in the original query (50,000 rows both), so I don't get why this join is special.
PS: I might also be doing other suboptimal things, please criticize.
select
*,
case
when t2.status = 1 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.04, 2)
when t2.status = 2 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.03, 2)
when t2.status = 3 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.02, 2)
when t2.status = 4 and t2.price > t2.buyprice then round((t2.price - t2.buyprice) * 0.01, 2)
else 0
end as bonus
from (
select *,
case
when t1.gratis = 1 then 10
when t1.price_vat = 0 or t1.price = 0 then
case
when t1.stock > 0 or soldLast180DaysQty > 0 then -1
when t1.stock = 0 then 12
end
when t1.buyprice = 0 then
case
when t1.stock > 0 then -1
when t1.stock = 0 then 12
end
when soldLast180DaysQty < 0 then 1
when t1.age_days < 60 then 9
when t1.last_import <= 180 then
case
when t1.soldLast180DaysQty <= t1.stock then 0
when t1.soldLast180DaysQty > t1.stock then 7
when t1.stock = 0 then 5
end
when t1.last_import >= 180 and t1.stock = 0 then
case
when soldLast180DaysQty > 0 then 10
when soldLast180DaysQty = 0 then 11
end
when t1.last_import >= 180 then
case
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) < 0.3 and t1.stock_retail / t1.stock >= 0.9 then 5
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0 and 0.1 then 1
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.1 and 0.2 then 2
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.2 and 0.3 then 3
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.3 and 0.4 then 4
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.4 and 0.7 then 0
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) >= 0.9 then 6
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.8 and 0.9 then 7
when t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) between 0.7 and 0.8 then 8
end
end as status,
round(t1.soldLast180DaysQty / nullif(t1.stock + t1.soldLast180DaysQty, 0) * 100, 0) as ratio
from (
select
si.anqid id,
CAST(rtrim(si.acident) as nvarchar(7)) as code,
CAST(rtrim(si.acname) as nvarchar(100)) as name,
si.anvat as vat,
si.ansaleprice as price_vat,
round(si.anrtprice, 2) as price,
cenovnik.clientPrice, -- <---------------------- This part
round(si.anbuyprice, 2) as buyprice,
concat(round(anpricesupp, 2), ' ', acpurchcurr) as fakturna,
round(si.anrtprice - si.anbuyprice, 2) as profit,
case
when si.anrtprice is not null and si.anrtprice > 0 and si.anbuyprice is not null and si.anbuyprice > 0
then round((si.anrtprice / si.anbuyprice - 1) * 100, 0)
end as margin,
cast(si.acfieldsa as nvarchar(12)) as [group],
cast(rtrim(si.acClassif2) as nvarchar(16)) as category,
cast(rtrim(ss.acsubject) as nvarchar(7)) as supplier_code,
cast(left(ss.acname2, 30) as nvarchar(30)) as supplier_name,
rtrim(si.acclassif) as rebate,
si.anFieldNA as webActive,
si.anfieldNF as gratis,
case
when si.acpicture is not null then 'true'
else 'false'
end as picture,
isnull((select sum(anstock) from the_stock where acident = si.acident and acwarehouse = '00051'), 0) as stock_warehouse,
isnull((select sum(anstock) from the_stock where acident = si.acident and acwarehouse <> '00051'), 0) as stock_retail,
isnull((select sum(anstock) from the_stock where acident = si.acident), 0) as stock,
isnull((select sum(anReserved) from the_stock where acident = si.acident), 0) as stock_reserved,
isnull((select sum(anvalue) from the_stock where acident = si.acident), 0) as stock_value,
(
select isnull(datediff(day, max(m.addate), getdate()), 9999)
from the_moveitem mi
left join the_move m
on mi.ackey = m.ackey
where mi.acident = si.acident and m.acDocType in ('1900', '1000', '6800', '1A00')
) as last_import,
isnull(round(soldLast180Days.soldLast180DaysQty, 0), 0) soldLast180DaysQty,
isnull(round(soldLast180Days.soldLast180DaysCogs, 0), 0) soldLast180DaysCogs,
isnull(round(soldLast180Days.soldLast180DaysRevenue, 0), 0) soldLast180DaysRevenue,
isnull(round(soldLast180Days.soldLast180DaysProfit, 0), 0) soldLast180DaysProfit,
datediff(day, si.adtimeins, getdate()) as age_days
from the_setitem si
/*
left join (
SELECT
si.acident sku,
case
when dogovoren.anPrice is null and matrica.anRebate is null then si.anRTPrice
when dogovoren.anPrice is not null then dogovoren.anPrice
when dogovoren.anPrice is null then si.anRTPrice * (1 - matrica.anRebate/100)
end as clientPrice
FROM tHE_SetItem si
left join (
select acident, anPrice
from vHE_SetSubjPriceItemExtToday
where acsubject = '1111'
) dogovoren
on dogovoren.acident = si.acident
left join (
select acClassif, anRebate
from vHE_SetSubjTypePriceCateg
where acSubjType = (select acsubjtypebuyer from tHE_SetSubj where acsubject = '1111')
) matrica
on si.acClassif = matrica.acClassif
) cenovnik
on cenovnik.sku = si.acident
*/
left join tHE_SetSubj ss
on ss.acsubject = si.acsupplier
left join (
select
mi.acident,
sum(mi.anQty) soldLast180DaysQty,
sum(mi.anQty * mi.anStockPrice) soldLast180DaysCogs,
sum(mi.anPVVATBase) soldLast180DaysRevenue,
sum(mi.anPVVATBase - mi.anQty * mi.anStockPrice) soldLast180DaysProfit
from the_moveitem mi
left join the_move m
on m.ackey = mi.ackey
where m.acDocType in ('3000', '3050', '3190', '3800', '3550', '3X10', '3950', '3500', '3510', '6700', '3A00', '3210', '3220', '3230', '3240', '3450', '3250', '3260', '3270', '3540', '3460', '3280', '3290', '3310', '3320', '3440', '3330', '3340', '3350', '3360', '3370', '3380', '3390', '3410', '3470', '3420', '3430', '3480', '3490', '3520', '3530', '3560', '3610', '2540', '2740', '2730'
) and m.addate >= getdate() - 180
group by mi.acident
) soldLast180Days
on soldLast180Days.acIdent = si.acident
) t1
) t2
where
t2.status < 11
order by
t2.status asc,
t2.stock_value desc
I am using SQL Server if it's relevant.
Not really an answer - but when I've had this problem I've just created temporary tables. In SQL Server you prefix the table name with # and they will get deleted when your session ends.
You might realise your nested table t1 as a temporary table #t1
CREATE TABLE #t1 (id INT, code NVARCHAR(7), etc...)
INSERT INTO #t1
select
si.anqid id,
CAST(rtrim(si.acident) as nvarchar(7)) as code,
CAST(rtrim(si.acname) as nvarchar(100)) as name,
etc..
SELECT * FROM .... #t1 ...
Replace all references to t1 with #t1

SQL query taking longer time to execute

I'm trying to execute the query. It take 32 min to execute. I have tried NOLOCK but only optimized it with 3 min.
the query is given below:-
SELECT PO.payday, PO.facility, PO.department, PO.workcenter, PO.shift, PO.team, PO.orderno, PO.fg_productno,
PO.sfg_productno, NoCarton = '1', NoPack = 5, NoCigarette = PO.nocigarette, VNC.sampleid, VNC.comment,
VNC.createdby, SampleDateTime = dbo.AF_GetUTCToLocal(VNC.UTCStartDate),
SampleTime = Cast(CONVERT(CHAR(10), VNC.utcstartdate, 101) AS DATETIME), VNC.ncgroup, VNC.productcomponent,
VNC.nc, VNC.ncname, VNC.weightingfactor, VNC.ConsumerSensitive, VNC.[lowunits], VNC.[low %], VNC.[highunits],
VNC.[high %], VNC.vqi, VNC.deepcontrol,
--Modification done for CHE10045964
PO.ResourceClassName
FROM
(SELECT PayDay = WCS.payday, Facility = R.facility, Department = R.department, WorkCenter = R.workcenter,
Shift = WCS.workperiod, Team = SD.teamid, OrderNo = WO.orderno,
FG_ProductNo = P.productno + Isnull('.' + P.productrevision, ''),
SFG_ProductNo = CASE
WHEN UCHSC.attribute_ != P.productno
THEN UCHSC.attribute_
ELSE NULL
END,
WO.actualstartdate, WO.actualcompletiondate,
NoCigarette = dbo.Af_getunitcharacteristicattribute(OD.unitid,'ZPPPI_ITEM_PACK') ,
RC.Name as ResourceClassName
FROM order_header OH
INNER JOIN dbo.wip_order WO ON OH.orderno = WO.orderno
INNER JOIN dbo.order_detail OD ON OD.orderno = WO.orderno
INNER JOIN dbo. product P ON WO.productid = P.id
INNER JOIN dbo.resource_ R ON R.resourcename = WO.resourcename AND R.resourcetype = WO.resourcetype
Inner Join dbo.Resource_Class RC ON R.ResourceClassID = RC.ID
INNER JOIN dbo.work_center_work_schedule WCS ON WO.oawipentityid = WCS.id
INNER JOIN at_work_center_work_schedule_detail SD ON WCS.id = SD.workcenterworkscheduleid
LEFT JOIN dbo.unit_characteristic UCHSC ON UCHSC.unitid = OD.unitid
AND UCHSC.characteristic = 'ZPPPI_SPA_CIGARETTE'
WHERE OH.ordertype = 23
GROUP BY WCS.payday, R.facility, R.department, R.workcenter, WCS.workperiod, SD.teamid,
WO.orderno, P.productno + Isnull('.' + P.productrevision, ''),
CASE
WHEN UCHSC.attribute_ != P.productno THEN UCHSC.attribute_
ELSE NULL
END,
WO.actualstartdate, WO.actualcompletiondate,
dbo.Af_getunitcharacteristicattribute(OD.unitid,'ZPPPI_ITEM_PACK'),
RC.Name
) PO INNER JOIN
(
SELECT NC.orderno, NC.sampleid, NC.comment, NC.deepcontrol, NC.createdby, NC.utcstartdate, NC.ncgroup, NC.productcomponent,
NC.nc, NC.ncname, NC.weightingfactor, NC.ConsumerSensitive, NC.[lowunits], NC.[low %], NC.[highunits], NC.[high %],
VQI = Round(NC.weightingfactor * ( Log (1 + [low %] / 3.0 + [high %]) ), 0),
--Added By Sukanya Biswas(CHE10045964)
NC.WorkCenter
FROM (SELECT orderno, b.sampleid, b.comment, b.deepcontrol, b.utcstartdate, b.ncgroup, b.productcomponent,
b.nc, b.ncname, b.weightingfactor, b.ConsumerSensitive, b.createdby,
[LowUnits] = Isnull(b.[1], 0),
[Low %] = CASE CONVERT(NVARCHAR(1),b.deepcontrol) + b.ncgroup
WHEN '0Bundle' THEN CASE WHEN (Isnull(b.[1], 0) * 100) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 100 END
WHEN '1Bundle' THEN CASE WHEN (Isnull(b.[1], 0) * 100) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 100 END
WHEN '0Pack' THEN CASE WHEN (Isnull(b.[1], 0) * NoofCigarette ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * NoofCigarette END
WHEN '1Pack' THEN CASE WHEN (Isnull(b.[1], 0) * NoofCigarette ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * NoofCigarette END
WHEN '0Cigarette' THEN CASE WHEN (Isnull(b.[1], 0) * 5 ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 5 END
WHEN '1Cigarette' THEN CASE WHEN (Isnull(b.[1], 0) * 1 ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 1 END
WHEN '0Filter' THEN CASE WHEN (Isnull(b.[1], 0) * 10 ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 10 END
WHEN '1Filter' THEN CASE WHEN (Isnull(b.[1], 0) * 10 ) > 100 THEN 100 ELSE Isnull(b.[1], 0) * 10 END
ELSE Isnull(b.[1], 0)
END, [HighUnits] = Isnull(b.[2], 0),
[High %] = CASE CONVERT(NVARCHAR(1),b.deepcontrol) + b.ncgroup
WHEN '0Bundle' THEN CASE WHEN (Isnull(b.[2], 0) * 100) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 100 END
WHEN '1Bundle' THEN CASE WHEN (Isnull(b.[2], 0) * 100) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 100 END
WHEN '0Pack' THEN CASE WHEN (Isnull(b.[2], 0) * NoofCigarette ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * NoofCigarette END
WHEN '1Pack' THEN CASE WHEN (Isnull(b.[2], 0) * NoofCigarette ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * NoofCigarette END
WHEN '0Cigarette' THEN CASE WHEN (Isnull(b.[2], 0) * 5 ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 5 END
WHEN '1Cigarette' THEN CASE WHEN (Isnull(b.[2], 0) * 1 ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 1 END
WHEN '0Filter' THEN CASE WHEN (Isnull(b.[2], 0) * 10 ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 10 END
WHEN '1Filter' THEN CASE WHEN (Isnull(b.[2], 0) * 10 ) > 100 THEN 100 ELSE Isnull(b.[2], 0) * 10 END
ELSE Isnull(b.[2], 0)
END ,
--Added By Sukanya Biswas(CHE10045964)
B.WorkCenter
FROM (SELECT D .orderno, SampleID = DTS.id,
--Added By Sukanya Biswas(CHE10045964)
DL.WorkCenter,
Comment = CASE Isnull(DTS.comment_, '')
WHEN '' THEN 'N/A'
ELSE DTS.comment_
END, UTCStartDate = DTS.actualstartdate, NC.ncgroup, NC.productcomponent, NC.nc, NC.ncname,
NC.weightingfactor, NC.ConsumerSensitive,
Severity = Isnull(QD.qualitydefectseverityid, 0),
QD.noofdefects, DTS.createdby, DeepControl = DTS.overridesumresults,
NoofCigarette = dbo.Af_getunitcharacteristicattribute(OD.unitid,'ZPPPI_ITEM_PACK')
FROM dbo.disposition D
INNER JOIN dbo.disposition_line DL ON D .disposition = DL.disposition
--Inner Join dbo.Work_Center WC ON DL.Workcenter = WC.Workcenter
INNER JOIN dbo.disposition_test DT ON DT.disposition = D .disposition
AND DT.linesequenceno = DL.linesequenceno
INNER JOIN dbo.disposition_test_sample DTS ON DTS.dispositiontestid = DT.id
LEFT JOIN quality_defect QD ON QD.dispositiontestsampleid = DTS.id
INNER JOIN dbo.AV_RPT_VSI_Nonconformity NC ON Isnull(QD.defectreasoncode, '00.00.00') = NC.nc
LEFT JOIN ORDER_DETAIL OD ON OD.ORDERNO=D.ORDERNO
WHERE DL.linecode = 'VQ'
) A
PIVOT (Sum(a.noofdefects)
FOR severity IN ([1],[2]))
B)
NC
As per your query filter and columns needed, please make index on respected columns.
By default SQL will create clustered index on your primary key, but you may create some other unclustered index on your table to make your execution faster.
You may find this link for your reference or Google it there are hundreds of article available on Internet for same.
"https://learn.microsoft.com/en-us/sql/t-sql/statements/create-index-transact-sql?view=sql-server-2017"

SQL Server 2014 stored procedure is slow

I have a stored procedure to calculate receipt and up to today I didn't have any problems with it until I had to execute it in a database with 100'000 rows. It's much too slow and runs for at least 3 hours, and it's not finished yet..
Is there a way to optimize this ?
Here the code:
Declare #sousTotal numeric(16,2),
#TotalTx1 numeric(18,4),
#TotalTx2 numeric(18,4),
#TotalTx3 numeric(18,4),
#Taux1 numeric(18,4),
#Taux2 numeric(18,4),
#Taux3 numeric(18,4),
#totalEscompte numeric(16,2),
#totalFacture numeric(16,2),
#MontantPaiement numeric(16,2)
Begin
BEGIN TRANSACTION;
BEGIN TRY
select top 1 #Taux1 = TauxTaxe1,#Taux2 = TauxTaxe2 ,#Taux3 = TauxTaxe3 from tbFactureEntete where ID = #IdFacture and IDCompagnie = #IDCie
select #sousTotal =sum(sousTotal),#TotalTx1 = sum(totalTx1),#TotalTx2 = sum(totalTx2),#TotalTx3 = sum(totalTx3),
#totalEscompte = sum(totalEscompte ),#totalFacture = sum(totalFacture) from(
select SUM(isnull(A.TotalLigne,0)) AS sousTotal ,
case taxe1 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux1 / 100
end AS totalTx1,
case taxe2 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux2 / 100
end AS totalTx2,
case taxe3 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux3 / 100
end AS totalTx3,
sum(isnull(MontantEscompte,0)) as totalEscompte ,sum(isnull(TotalLigne,0)) + case taxe1 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux1 / 100
end +
case taxe2 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux2 / 100
end +
case taxe3 when 0 then 0
when 1 then SUM(isnull(A.TotalLigne,0)) * #Taux3 / 100
end as totalFacture
from tbfactureDetail A
where IdFacture = #IdFacture and A.IDCompagnie = #IDCie
group by taxe1,taxe2,taxe3) as AA
select #MontantPaiement = SUM(MontantPaiement) from tbFacturePaiement
where IdFacture = #IdFacture
update tbFactureEntete
set Total_AvantTaxe = #sousTotal,
totalTaxe1 = #TotalTx1,
totalTaxe2 = #TotalTx2,
totalTaxe3 = #TotalTx3,
TotalEscompte = isnull(#totalEscompte,0),
TotalFacture = isnull(#totalFacture,0),
TotalPaiementCR = isnull(#MontantPaiement,0) ,
TotalSolde = isnull(#totalFacture,0) - isnull(#MontantPaiement,0)
where ID = #IdFacture and IDCompagnie = #IDCie
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF ##TRANCOUNT > 0
COMMIT TRANSACTION;
return
End
Thanks again!!
Depending on the cardinality of IdFacture and IDCompagnie in table tbfactureDetail, an index would help things along if one is missing.
if there are many different values of IdCompagnie for the many different values of IDFacture
CREATE NONCLUSTERED INDEX IX_NewIdx_Name
ON tbfactureDetail (IdFacture,IdCompagnie)
If there are relatively few IdCompagnie per IDfacture, you could use an Include.
CREATE NONCLUSTERED INDEX IX_NewIdx_Name
ON tbfactureDetail (IdFacture)
INCLUDE (IdCompagnie)
I think this is mathematically the same and a bit more optimal for the code.
BEGIN TRY
select top 1 #Taux1 = TauxTaxe1
, #Taux2 = TauxTaxe2
, #Taux3 = TauxTaxe3
from tbFactureEntete
where ID = #IdFacture and IDCompagnie = #IDCie
select #sousTotal =sum(isnull(A.TotalLigne,0))
, #TotalTx1 = sum(taxe1 * isnull(A.TotalLigne,0) * #Taux1 / 100)
, #TotalTx2 = sum(taxe2 * isnull(A.TotalLigne,0) * #Taux2 / 100)
, #TotalTx3 = sum(taxe3 * isnull(A.TotalLigne,0) * #Taux3 / 100)
, #totalEscompte = sum(isnull(MontantEscompte,0) )
, #totalFacture =
sum(taxe1 * isnull(A.TotalLigne,0) * #Taux1 / 100) +
sum(taxe2 * isnull(A.TotalLigne,0) * #Taux2 / 100) +
sum(taxe3 * isnull(A.TotalLigne,0) * #Taux3 / 100)
from tbfactureDetail A
where IdFacture = #IdFacture and A.IDCompagnie = #IDCie
select #MontantPaiement = SUM(MontantPaiement)
from tbFacturePaiement
where IdFacture = #IdFacture
update tbFactureEntete
set Total_AvantTaxe = #sousTotal
, totalTaxe1 = #TotalTx1
, totalTaxe2 = #TotalTx2
, totalTaxe3 = #TotalTx3
, TotalEscompte = isnull(#totalEscompte,0)
, TotalFacture = isnull(#totalFacture,0)
, TotalPaiementCR = isnull(#MontantPaiement,0)
, TotalSolde = isnull(#totalFacture,0) - isnull(#MontantPaiement,0)
where ID = #IdFacture and IDCompagnie = #IDCie
END TRY

SQL Query not producing 'Disabled' jobs within the results, alongside 'Failed' jobs

I have the following code for a SQL Query I'm working on..
DECLARE #Date datetime
SET #Date = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
DECLARE #jobHistory TABLE
(
job_id UNIQUEIDENTIFIER
, success INT
, cancel INT
, fail INT
, retry INT
, last_execution_id INT
, last_duration CHAR(8)
, last_execution_start DATETIME
);
WITH lastExecution
AS
(
SELECT job_id
, MAX(instance_id) AS last_instance_id
FROM msdb.dbo.sysjobhistory
WHERE step_id = 0
GROUP BY job_id
)
INSERT INTO #jobHistory
SELECT sjh.job_id
, SUM(CASE WHEN sjh.run_status = 1 AND step_id = 0 THEN 1 ELSE 0 END) AS success
, SUM(CASE WHEN sjh.run_status = 3 AND step_id = 0 THEN 1 ELSE 0 END) AS cancel
, SUM(CASE WHEN sjh.run_status = 0 AND step_id = 0 THEN 1 ELSE 0 END) AS fail
, SUM(CASE WHEN sjh.run_status = 2 THEN 1 ELSE 0 END) AS retry
, MAX(CASE WHEN sjh.step_id = 0 THEN instance_id ELSE NULL END) last_execution_id
, SUBSTRING(CAST(MAX(CASE WHEN le.job_id IS NOT NULL THEN sjh.run_duration ELSE NULL END) + 1000000 AS VARCHAR(7)),2,2) + ':'
+ SUBSTRING(CAST(MAX(CASE WHEN le.job_id IS NOT NULL THEN sjh.run_duration ELSE NULL END) + 1000000 AS VARCHAR(7)),4,2) + ':'
+ SUBSTRING(CAST(MAX(CASE WHEN le.job_id IS NOT NULL THEN sjh.run_duration ELSE NULL END) + 1000000 AS VARCHAR(7)),6,2)
AS last_duration
, MAX(CASE WHEN le.last_instance_id IS NOT NULL THEN
CONVERT(datetime, RTRIM(run_date))
+ ((run_time / 10000 * 3600)
+ ((run_time % 10000) / 100 * 60)
+ (run_time % 10000) % 100) / (86399.9964)
ELSE '1900-01-01' END) AS last_execution_start
FROM msdb.dbo.sysjobhistory AS sjh
LEFT JOIN lastExecution AS le
ON sjh.job_id = le.job_id
AND sjh.instance_id = le.last_instance_id
GROUP BY sjh.job_id;
DECLARE #weekDay TABLE (
mask INT
, maskValue VARCHAR(32)
);
INSERT INTO #weekDay
SELECT 1, 'Sunday' UNION ALL
SELECT 2, 'Monday' UNION ALL
SELECT 4, 'Tuesday' UNION ALL
SELECT 8, 'Wednesday' UNION ALL
SELECT 16, 'Thursday' UNION ALL
SELECT 32, 'Friday' UNION ALL
SELECT 64, 'Saturday';
WITH myCTE
AS(
SELECT sched.name AS 'scheduleName'
, sched.schedule_id
, jobsched.job_id
, CASE
WHEN sched.freq_type = 1
THEN 'Once'
WHEN sched.freq_type = 4
AND sched.freq_interval = 1
THEN 'Daily'
WHEN sched.freq_type = 4
THEN 'Every ' + CAST(sched.freq_interval AS VARCHAR(5)) + ' days'
WHEN sched.freq_type = 8 THEN
REPLACE( REPLACE( REPLACE((
SELECT maskValue
FROM #weekDay AS x
WHERE sched.freq_interval & x.mask <> 0
ORDER BY mask FOR XML RAW)
, '"/><row maskValue="', ', '), '<row maskValue="', ''), '"/>', '')
+ CASE
WHEN sched.freq_recurrence_factor <> 0
AND sched.freq_recurrence_factor = 1
THEN '; weekly'
WHEN sched.freq_recurrence_factor <> 0
THEN '; every '
+ CAST(sched.freq_recurrence_factor AS VARCHAR(10)) + ' weeks' END
WHEN sched.freq_type = 16 THEN 'On day '
+ CAST(sched.freq_interval AS VARCHAR(10)) + ' of every '
+ CAST(sched.freq_recurrence_factor AS VARCHAR(10)) + ' months'
WHEN sched.freq_type = 32 THEN
CASE
WHEN sched.freq_relative_interval = 1 THEN 'First'
WHEN sched.freq_relative_interval = 2 THEN 'Second'
WHEN sched.freq_relative_interval = 4 THEN 'Third'
WHEN sched.freq_relative_interval = 8 THEN 'Fourth'
WHEN sched.freq_relative_interval = 16 THEN 'Last'
END +
CASE
WHEN sched.freq_interval = 1 THEN ' Sunday'
WHEN sched.freq_interval = 2 THEN ' Monday'
WHEN sched.freq_interval = 3 THEN ' Tuesday'
WHEN sched.freq_interval = 4 THEN ' Wednesday'
WHEN sched.freq_interval = 5 THEN ' Thursday'
WHEN sched.freq_interval = 6 THEN ' Friday'
WHEN sched.freq_interval = 7 THEN ' Saturday'
WHEN sched.freq_interval = 8 THEN ' Day'
WHEN sched.freq_interval = 9 THEN ' Weekday'
WHEN sched.freq_interval = 10 THEN ' Weekend'
END
+ CASE
WHEN sched.freq_recurrence_factor <> 0
AND sched.freq_recurrence_factor = 1
THEN '; monthly'
WHEN sched.freq_recurrence_factor <> 0
THEN '; every '
+ CAST(sched.freq_recurrence_factor AS VARCHAR(10)) + ' months'
END
WHEN sched.freq_type = 64 THEN 'StartUp'
WHEN sched.freq_type = 128 THEN 'Idle'
END AS 'frequency'
, ISNULL('Every ' + CAST(sched.freq_subday_interval AS VARCHAR(10)) +
CASE
WHEN sched.freq_subday_type = 2 THEN ' seconds'
WHEN sched.freq_subday_type = 4 THEN ' minutes'
WHEN sched.freq_subday_type = 8 THEN ' hours'
END, 'Once') AS 'subFrequency'
, REPLICATE('0', 6 - LEN(sched.active_start_time))
+ CAST(sched.active_start_time AS VARCHAR(6)) AS 'startTime'
, REPLICATE('0', 6 - LEN(sched.active_end_time))
+ CAST(sched.active_end_time AS VARCHAR(6)) AS 'endTime'
, REPLICATE('0', 6 - LEN(jobsched.next_run_time))
+ CAST(jobsched.next_run_time AS VARCHAR(6)) AS 'nextRunTime'
, CAST(jobsched.next_run_date AS CHAR(8)) AS 'nextRunDate'
FROM msdb.dbo.sysschedules AS sched
JOIN msdb.dbo.sysjobschedules AS jobsched
ON sched.schedule_id = jobsched.schedule_id
WHERE sched.enabled = 1
)
SELECT job.name AS [Job Name]
, CASE WHEN job.enabled = 1 THEN 'Enabled' ELSE 'Disabled' END AS [Job Status]
, COALESCE(sched.subFrequency, '') AS [Frequency]
, COALESCE(jh.last_duration, '') AS [Last Run Duration]
, COALESCE(jh.last_execution_start, '') AS [Last Run Time/Date]
FROM msdb.dbo.sysjobs AS job
LEFT JOIN myCTE AS sched
ON job.job_id = sched.job_id
LEFT JOIN #jobHistory AS jh
ON job.job_id = jh.job_id
WHERE jh.last_execution_start >= DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
AND job.name like '%MAINTENANCE - BACKUP%'
ORDER BY nextRunDate;
but although the results show the expected 'Failed' jobs, the 'Disabled' jobs are missing. I have also had help with this, as I have no SQL experience.
This Query has been created to check the Job History of roughtly 5/10 Backup Jobs within a 24 hour period, noting all the Failures (even if the last Run Succeeded). The seconds on the [Last Run Time/Date] also seem to be off, showing as soemthign like '50:00.0'
I also need a new column for the [Last Run Outcome] - to show if the Job 'Failed/Succeeded' as a Status.
Please let me know if you require any further information or a PasteBin of my code.

Query Runs Slower The Second Time

I have this massive query that I can typically run in under 2 minutes. However, when I run it a second time about a minute after, it goes on infinitely... so I kill the process and my SSMS session. I don't have any other jobs running in the background.
Is something else being retained on the server? I think I'm missing something as far as how SQL Server works.
Thanks.
EDIT: Here's the SQL (had to do a little obfuscation)
SELECT pl.OrangeLocationID ,
e.EventID ,
cr.Title AS [Event Type] ,
su.LastName + ', ' + su.FirstName AS FMR ,
CONVERT(VARCHAR(20), pl.Report_Date, 101) AS [Report Entry Date] ,
l.Name ,
l.Number ,
ll.SodaPopLocationID AS [SodaPop Location ID] ,
l.Zip ,
c.Channel ,
pl.DT AS [ReportedDate] ,
RIGHT(pl.DT_start, 8) AS [ReportedStartTime] ,
RIGHT(pl.DT_end, 8) AS [ReportedEndTime] ,
[CMS].dbo.dDateDiff(pl.DT_start, pl.DT_end) AS [ReportedDuration] ,
pl.scheduled_date AS [ScheduledDate] ,
RIGHT(pl.scheduled_start, 8) AS [ScheduledStartTime] ,
RIGHT(pl.scheduled_end, 8) AS [ScheduledEndTime] ,
[CMS].dbo.dDateDiff(pl.scheduled_start, pl.DT_end) AS [ScheduledDuration] ,
e.HoursPaid AS [Rep Hours Worked] ,
ISNULL(PP.[RepCount], 0) AS [RepCount] ,
CASE WHEN [CMS].dbo.dDateDiff(pl.DT_start, pl.DT_end) = ( e.HoursPaid / ISNULL(PP.[RepCount], 1) )
THEN [CMS].dbo.oa_HourDateDiff(pl.DT_start, pl.DT_end)
WHEN [CMS].dbo.dDateDiff(pl.scheduled_start, pl.DT_end) = ( e.HoursPaid / ISNULL(PP.[RepCount], 1) )
THEN [CMS].dbo.oa_HourDateDiff(pl.scheduled_start, pl.DT_end)
ELSE ( e.HoursPaid / ISNULL(PP.[RepCount], 1) )
END AS [FinalDuration] ,
g.[Description] AS [OA Market] ,
g.SodaPop_Region AS [SodaPop Region] ,
g.SodaPop_Area AS [SodaPop Area] ,
coup4 ,
coupo ,
coupo_e ,
card_num ,
promo ,
promo_no ,
promo_no_o ,
highlight1 ,
highlight2 ,
highlight3 ,
mgmt_reaction ,
mgmt_reaction_e ,
comm_p ,
comm_n ,
r.comments ,
s_fname ,
s_lname ,
v_title ,
ll.KeyAccountCorp AS [Key Account Corp.] ,
interact_new + interact_rep AS [interact_total] ,
samp_new + samp_rep AS [samp_total] ,
purch_new + purch_rep AS [purch_total] ,
23 / ( NULLIF(( interact_new + interact_rep ), 0) * 1.0 ) AS [Int_Crate] ,
CASE WHEN sampletype = 11 THEN ( purch_new + purch_rep ) / ( NULLIF(( samp_new + samp_rep ), 0) * 1.0 )
ELSE NULL
END AS [Samp_Crate] ,
coup1 + coup2 AS [coup_total] ,
CASE WHEN coup1 + coupo > 0 THEN 1
ELSE 0
END AS [CoupDist] ,
DATEPART(month, pl.DT) AS [Visit_Month] ,
DATEPART(quarter, pl.DT) AS [Quarter] ,
DATEPART(weekday, pl.DT) AS [Weekday] ,
CASE DATEPART(weekday, pl.DT)
WHEN 6 THEN 'Fri'
WHEN 7 THEN 'Sat'
WHEN 1 THEN 'Sun'
ELSE 'Mon-Thurs'
END AS [Weekday_Grouped] ,
CASE WHEN dbo.Exception(pl.OrangeLocationID, 12) = 1
OR dbo.Exception(pl.OrangeLocationID, 13) = 1
OR dbo.Exception(pl.OrangeLocationID, 14) = 1 THEN 1
ELSE 0
END AS [EVolume] ,
CASE WHEN dbo.DoesHaveException(pl.OrangeLocationID, 18) = 1 THEN 1
ELSE 0
END AS [CVolume] ,
CASE WHEN dbo.eException(pl.OrangeLocationID, 9) = 1
OR dbo.eException(pl.OrangeLocationID, 22) = 1 THEN 1
ELSE 0
END AS [Volumes] ,
CASE WHEN dbo.eException(pl.OrangeLocationID, 8) = 1
OR dbo.eException(pl.OrangeLocationID, 21) = 1 THEN 1
ELSE 0
END AS [Sales Price] ,
CASE WHEN dbo.eException(pl.OrangeLocationID, 11) = 1 THEN 1
ELSE 0
END AS [Sample Volume] ,
ISNULL(i.[NormalizedSold], 0) AS [EQBottlesSold] ,
CASE WHEN ISNULL(purch_new, 0) = 0 THEN 0
ELSE ISNULL(i.[NormalizedSold], 0) / ( purch_new + purch_rep )
END AS [EQBottlesSoldPerPurch] ,
ac.AvgSales ,
ac.STDEVSales ,
( ISNULL(i.[NormalizedSold], 0) - ac.AvgSales ) / ac.STDEVSales AS [sl] ,
ac.AvgPurchasers ,
ac.STDEVPurchasers ,
( ISNULL(r.purch_new, 0) - ac.AvgPurchasers ) / ac.STrchasers AS [ZScore_Purchasers] ,
ac.AvgConversions ,
ac.STDEVConversions ,
( ISNULL(( purch_new + purch_rep ) / ( NULLIF(( interact_new ), 0) ), 0) - ac.AvgConversions )
/ ac.STDEVConversions AS [ZScore_Conversions] ,
ac.[AvgSalesPerPurchaser] ,
ac.[STDEVSalesPerPurchaser] ,
( ISNULL(( CASE WHEN ISNULL(purch_new, 0) = 0 THEN 0
ELSE ISNULL(i.[NormalizedSold], 0) / ( purch_new + purch_rep )
END ), 0) - ac.[AvgSalesPerPurchaser] ) / ac.[STDEVSalesPerPurchaser] AS [SalesPerPurchaser] ,
( ( ( ISNULL(i.[NormalizedSold], 0) - ac.AvgSales ) / ac.STDEVSales )
+ ( (ISNULL(( CASE WHEN ISNULL(purch_new + purch_rep, 0) = 0 THEN 0
ELSE ISNULL(i.[NormalizedSold], 0) / ( purch_new + purch_rep )
END ), 0) - ac.[AvgSalesPerPurchaser]) ) ) / 4 AS [core] ,
( ( (( ISNULL(i.[NormalizedSold], 0) - ac.AvgSales ) / ac.STDEVSales) ) / 4 ) + 3 AS [core] ,
su.aaUserID ,
l.LsocationID
FROM [CMS_SodaPop].dbo.Schedule pl WITH ( NOLOCK )
INNER JOIN [CMS_SodaPop].dbo.Report r WITH ( NOLOCK ) ON r.OrangeLocationID = pl.OrangeLocationID
INNER JOIN [CMS].dbo.Users su WITH ( NOLOCK ) ON su.UserID = pl.Rep_FMR
INNER JOIN [CMS].dbo.Locations l WITH ( NOLOCK ) ON l.LocationID = pl.LocationID
INNER JOIN [CMS].dbo.OrangeReports cr WITH ( NOLOCK ) ON cr.RedID = pl.RedID
INNER JOIN [CMS_SodaPop].dbo.Events e WITH ( NOLOCK ) ON e.OrangeLocationID = pl.OrangeLocationID
INNER JOIN [CMS_SodaPop].dbo.MarketList g WITH ( NOLOCK ) ON g.GroupID = pl.GroupID
INNER JOIN [CMS_SodaPop].dbo.Locations ll WITH ( NOLOCK ) ON ll.LocationID = pl.LocationID
LEFT JOIN [CMS_SodaPop].dbo.Channels c WITH ( NOLOCK ) ON ll.ChannelID = c.ChannelID
LEFT JOIN ( SELECT PLocationID ,
COUNT(DISTINCT UserID) AS [RepCount]
FROM [CMS_roll].dbo.rollItems WITH ( NOLOCK )
WHERE RedID = 154
GROUP BY OrangeLocationID
) PP ON PP.OrangeLocationID = pl.OrangeLocationID
LEFT JOIN ( SELECT OrangeLocationID ,
SUM(NormalizedSold) AS [NormalizedSold]
FROM [Analysis].dbo.[vSodaPop_Retail_Inventory] WITH ( NOLOCK )
GROUP BY OrangeLocationID
) i ON i.OrangeLocationID = pl.OrangeLocationID
LEFT JOIN [Analysis].dbo.[vSodaPop_Calculations] ac WITH ( NOLOCK ) ON ac.[Quarter] = CASE WHEN DATEPART(MM,
[DT]) IN ( 10,
11, 12 ) THEN 4
END
AND ac.[Year] = DATEPART(YY, pl.DT)
WHERE pl.Activity = 1
AND pl.RedID = 154
AND pl.GroupID <> 444
AND pl.[DT] < GETDATE()
AND DATEPART(YY, [DT]) >= 2010
AND ISNULL(i.NormalizedSold, 0) >= 0
AND DATEPART(year, GETDATE()) = DATEPART(year, r.Insert_Date)
Would have to see the query to really dig in however..
you could try adding OPTION (RECOMPILE) to the end of the query to force it to create a new execution plan.
Are you using Temp Tables?
Cursors not deallocated & closed?
You can look at Profiler to see if anything looks different between the 2 executions.
Are you sure it isn't being blocked by another process the second time?
What happens if you execute
CHECKPOINT;
GO;
DBCC DROPCLEANBUFFERS;
GO;
DBCC FREEPROCCACHE;
GO;
between the queries? This is not really a solution but will help diagnosis.