I want to replace the 1st and 2nd parameter in DATEADD function depending on the result of cteTable. Is this something possible? Do I need to create a parameter? Thank you in advance. Happy new year!
;with cteDP as(
SELECT CODE, MEASSUREMENT, DEFEXPIRYDATEDAYS,
CASE WHEN MEASSUREMENT = 0 THEN 'DAY'
WHEN MEASSUREMENT = 1 THEN 'WEEK'
WHEN MEASSUREMENT = 2 THEN 'MONTH'
WHEN MEASSUREMENT = 3 THEN 'YEARS'
ELSE 'SECOND'
END AS MEASUREMENTINWORD
FROM PW001C06 C06 WHERE CODE IN ('ADC','MMC')
)
select * from cteDP
UPDATE P05
SET P05.EXPIRYDATE = CASE
WHEN P05.CODE = 'ADC' THEN DATEADD('cteDocProperties.MEASUREMENTINWORD', #2nd parameter, EXPIRYDATE)
-- WHEN P05.CODE = 'MMC' THEN DATEADD(YEAR, 4, EXPIRYDATE)
-- WHEN P05.CODE = 'LD00' THEN DATEADD(YEAR, 3, EXPIRYDATE)
ELSE EXPIRYDATE
END
FROM PW001P05 P05
INNER JOIN cteDP
ON cteDP.CODE = P05.CODE
WHERE P05.PIN = 1
AND P05.CODE IN ('ADC','MMC')
You can directly JOIN to the table expression:
UPDATE P05
SET
P05.EXPIRYDATE = CASE
WHEN P05.CODE = 'ADC' THEN
CASE WHEN MEASUREMENTINWORD = 'SECOND'
THEN DATEADD(SECOND, MEASSUREMENT, EXPIRYDATE)
CASE WHEN MEASUREMENTINWORD = 'DAY'
THEN DATEADD(DAY, MEASSUREMENT, EXPIRYDATE)
CASE WHEN MEASUREMENTINWORD = 'MONTH'
THEN DATEADD(MONTH, MEASSUREMENT, EXPIRYDATE)
CASE WHEN MEASUREMENTINWORD = 'YEAR'
THEN DATEADD(YEAR, MEASSUREMENT, EXPIRYDATE)
ELSE EXPIRYDATE
END
FROM PW001P05 P05
INNER JOIN
(
SELECT
CODE
, MEASSUREMENT
, DEFEXPIRYDATEDAYS
, CASE
WHEN MEASSUREMENT = 0 THEN 'DAY'
WHEN MEASSUREMENT = 1 THEN 'WEEK'
WHEN MEASSUREMENT = 2 THEN 'MONTH'
WHEN MEASSUREMENT = 3 THEN 'YEARS'
ELSE 'SECOND'
END AS MEASUREMENTINWORD
FROM PW001C06 C06 WHERE CODE IN ('ADC','MMC')
) cteDP
ON cteDP.CODE = P05.CODE
WHERE P05.PIN = 1
AND P05.CODE IN ('ADC','MMC')
Related
I have written a procedure that collects data from 4 tables and issues a general report for the day.
There are two similar SQL queries in the procedure, the execution time of each of which is more than 1 seconds, respectively, the procedure execution time is more than 2 seconds, can this be optimized?
CREATE PROCEDURE cv
#dt AS SMALLDATETIME
AS
SELECT
(SELECT ISNULL(SUM(CASE WHEN PrePayDate IS NULL THEN '0' ELSE Price * Kvo END), 0)
FROM RCassa
WHERE DataRC = #dt) AS crMagPDP,
(SELECT ISNULL(SUM(SumPrice), 0) -
ISNULL(SUM(CASE WHEN PrePayDate IS NULL THEN '0' ELSE Price * Kvo END), 0)
FROM RCassa
WHERE DataRC = #dt) AS crMag,
for browse
2 queries are shown just as an example, there are more subqueries.
Whole procedure:
SET ANSI_NULLS OFF
SET QUOTED_IDENTIFIER OFF
GO
CREATE PROCEDURE CV
#dt as SMALLDATETIME
AS
SELECT
(SELECT isnull(sum(CASE WHEN PrePayDate IS NULL THEN '0' ELSE Price * Kvo END), 0)
FROM RCassa WHERE DataRC = #dt) as crMagPDP,
(SELECT ISNULL(sum(SumPrice), 0) - isnull(sum(CASE WHEN PrePayDate IS NULL THEN '0' ELSE Price * Kvo END), 0)
FROM RCassa WHERE DataRC = #dt) AS crMag,
(SELECT ISNULL(SUM(What_Done.Price_Sp), 0)
FROM What_Done
INNER JOIN ORDERS ON What_Done.uid = ORDERS.uid
WHERE What_Done.Price_Sp >= 0 AND What_Done.Nal <> 0
AND CONVERT(datetime, CONVERT(varchar(12), ORDERS.Out_Date)) = #dt
) as crParts,
(SELECT ISNULL(SUM(What_Done.Price_Total - ISNULL(What_Done.Price_Diag, 0)), 0)
FROM What_Done INNER JOIN ORDERS ON What_Done.uid = ORDERS.uid
WHERE What_Done.Price_Total > 0 AND What_Done.Nal <> 0
AND CONVERT(datetime, CONVERT(varchar(12), ORDERS.Out_Date)) = #dt
) + (SELECT ISNULL(SUM(What_Done.Price_Diag), 0)
FROM What_Done
INNER JOIN ORDERS ON What_Done.uid = ORDERS.uid
WHERE What_Done.Price_Total >= 0 AND What_Done.Nal <> 0
AND CONVERT(datetime, CONVERT(varchar(12), ORDERS.Order_Date)) = #dt
) as crCassa,
(SELECT ISNULL(SUM(What_Done.Price_Diag), 0)
FROM What_Done
INNER JOIN ORDERS ON What_Done.uid = ORDERS.uid
WHERE What_Done.Price_Total >= 0 AND What_Done.Nal <> 0 AND What_Done.BCard_IN <> 0
AND CONVERT(datetime, CONVERT(varchar(12), ORDERS.Order_Date)) = #dt
) + (SELECT ISNULL(SUM(What_Done.Price_Total - ISNULL(What_Done.Price_Diag, 0)), 0)
FROM What_Done
INNER JOIN ORDERS ON What_Done.uid = ORDERS.uid
WHERE What_Done.Price_Total >= 0 AND What_Done.Nal <> 0 AND What_Done.BCard_OUT <> 0
AND CONVERT(datetime, CONVERT(varchar(12), ORDERS.Out_Date)) = #dt
) as crBCard,
(SELECT ISNULL(SUM(Summ), 0) FROM RevOrd WHERE Summ >= 0 AND Nal <> 0 AND DateOrd = #dt) as crNal,
(SELECT ISNULL(SUM(Summ), 0) FROM RevOrd WHERE Summ >= 0 AND Nal = 0 AND DateOrd = #dt) as crCard,
(SELECT ISNULL(Sum(SumTotal), 0) FROM LineOrders WHERE DataOut = #dt) as crLine,
(SELECT ISNULL(Sum(SumTotal), 0) FROM LineOrders WHERE DataOut = #dt and Dost <> 0) as crDostavka,
(SELECT ISNULL(SUM(What_Done.BCard_IN_Sum), 0)
FROM What_Done
INNER JOIN ORDERS ON What_Done.uid = ORDERS.uid
WHERE What_Done.Price_Total >= 0 AND What_Done.Nal <> 0 AND What_Done.BCard_IN <> 0
AND CONVERT(datetime, CONVERT(varchar(12), ORDERS.Order_Date)) = #dt
)+(SELECT ISNULL(SUM(What_Done.BCard_OUT_Sum), 0)
FROM What_Done
INNER JOIN ORDERS ON What_Done.uid = ORDERS.uid
WHERE What_Done.Price_Total >= 0 AND What_Done.Nal <> 0 AND What_Done.BCard_OUT <> 0
AND CONVERT(datetime, CONVERT(varchar(12), ORDERS.Out_Date)) = #dt
) as crBCardCorrect
for browse
Assuming the criteria for the sub-queries are identical and filter on DataRC = #dt and use the same data source RCassa, then you can simplify the query like this:
SELECT
isnull(sum(CASE WHEN PrePayDate IS NULL THEN '0' ELSE Price * Kvo END), 0) as crMagPDP,
ISNULL(sum(SumPrice), 0) - isnull(sum(CASE WHEN PrePayDate IS NULL THEN '0' ELSE Price * Kvo END), 0) AS crMag,
...
FROM RCassa
WHERE DataRC = #dt
If the outer select is from other table[s] use APPLY
SELECT
isnull(t.crMagPDP, 0) crMagPDP,
isnull(t.crMag, 0) crMag,
..
FROM
..
OUTER APPLY (
SELECT
sum(CASE WHEN PrePayDate IS NULL THEN 0 ELSE Price * Kvo END) as crMagPDP,
sum(SumPrice) - sum(CASE WHEN PrePayDate IS NULL THEN 0 ELSE Price * Kvo END) AS crMag,
...
FROM RCassa
WHERE DataRC = #dt
) t
in the following select statement I want to put two values when
#PAPCOD = 'SIN' = values are 'DD' and 'SD'
and
#PAPCOD = 'ENG' = values are 'DI' and 'SI'
how can i do this. Only I can put one value
SELECT ISNULL((SUM(Con_Amount)),0) +
(SELECT DISTINCT ISNULL(SUM(Correspondent_Other_Payments.Oth_Pmt_Amount),0)
FROM Correspondent_Other_Payments
WHERE Correspondent_Other_Payments.Oth_Cnt_Code = Contributions.Con_Cnt_Code and
Correspondent_Other_Payments.Oth_Prv_Code = Contributions.Con_Prv_Code and
Correspondent_Other_Payments.Oth_Dst_Code = Contributions.Con_Dst_Code and
Correspondent_Other_Payments.Oth_Cor_Code = Contributions.Con_Cor_Code and
Correspondent_Other_Payments.Oth_Pmt_Date = CONVERT(DATE, #PubDatE, 111) and
Correspondent_Other_Payments.Oth_AuditChk = 'Y')
FROM Contributions
INNER JOIN Correspondent_Master
ON Contributions.Con_Cnt_Code = Correspondent_Master.Cor_Country_Code and
Contributions.Con_Prv_Code = Correspondent_Master.Cor_Province_Code and
Contributions.Con_Dst_Code = Correspondent_Master.Cor_District_Code and
Contributions.Con_Cor_Code = Correspondent_Master.Cor_Code
WHERE Con_paper LIKE
CASE
WHEN #PapCod = 'SIN' THEN
'DD'
WHEN #PapCod = 'ENG' THEN
'DI'
ELSE
#PapCod
END and
(Con_PubDate BETWEEN CONVERT(DATE, #PubDatB, 111) and
CONVERT(DATE, #PubDatE, 111)) and
Contributions.Audit_Chk = 'Y' /* Audited */
GROUP BY Contributions.Con_Cnt_Code,
Contributions.Con_Prv_Code,
Contributions.Con_Dst_Code,
Contributions.Con_Cor_Code,
Contributions.Con_Paper
ORDER BY Contributions.Con_Cnt_Code,
Contributions.Con_Prv_Code,
Contributions.Con_Dst_Code,
Contributions.Con_Cor_Code
Just add an OR replicate the same CASE and change the values to SD and SI.
DECLARE
#t TABLE(Con_Paper VARCHAR(50), Con_Amount INT)
INSERT INTO #t VALUES
('DD', 100)
,('SD', 250)
,('BN',450)
,('DD',50)
,('DI',350)
,('NL',65)
DECLARE #PapCod VARCHAR(50) = 'ENG'
SELECT SUM(Con_Amount)
FROM #t
WHERE
(Con_paper LIKE
CASE
WHEN #PapCod = 'SIN' THEN 'DD'
WHEN #PapCod = 'ENG' THEN 'DI'
ELSE #PapCod
END
OR
Con_paper LIKE
CASE
WHEN #PapCod = 'SIN' THEN 'SD'
WHEN #PapCod = 'ENG' THEN 'SI'
ELSE #PapCod
END
)
i have the following query.
SELECT DISTINCT datepart(day, eventdetails_datetime) as dates , bu_events.event_daysbeforeType
FROM "bu_events"
INNER JOIN "bu_eventdetails" ON "bu_eventdetails"."event_id" = "bu_events"."event_id"
WHERE "bu_events"."is_active" = 1
AND "bu_events"."is_deleted" =0
AND "bu_eventdetails"."is_active" = 1
AND "bu_eventdetails"."is_deleted" =0
AND "bu_events"."service_id" = '31'
AND (DATEDIFF(Minute, BU_EventDetails.eventDetails_datetime, '2017-07-12 10:33:19') <=0 or coalesce(event_always_available,0) = 1 )
AND
(DATEDIFF(d, '2017-07-12 10:33:19',BU_EventDetails.eventDetails_datetime) >= coalesce(BU_Events.event_daysbefore, 0) or coalesce(event_always_available,0) = 1 )
AND ( select max(availabletable_amount)
from bu_availabletable
inner join bu_eventdetails on bu_eventdetails.eventdetail_id = bu_availabletable.eventdetail_id
inner join bu_eventpricegroups on bu_eventpricegroups.event_id = bu_eventdetails.event_id
where bu_availabletable.eventdetail_id = bu_eventdetails.eventdetail_id
and bu_eventpricegroups.eventpricegroup_always_available = 0 ) > 0
AND datepart(Month,eventdetails_datetime) = 07
AND datediff(d,getdate(),eventdetails_datetime)>=0
What i'm trying to do, is if bu_events.event_daysbeforeType is 1 then (DATEDIFF(d, '2017-07-12 10:33:19',BU_EventDetails.eventDetails_datetime) >= coalesce(BU_Events.event_daysbefore, 0) or coalesce(event_always_available,0) = 1 ) and if it's 2 then (DATEDIFF(hour, '2017-07-12 10:33:19',BU_EventDetails.eventDetails_datetime) >= coalesce(BU_Events.event_daysbefore, 0) or coalesce(event_always_available,0) = 1 )
So depending on bu_events.event_daysbeforeType i want to datediff with D or HOUR.
What i've tried so far but not working is this:
SELECT DISTINCT datepart(day, eventdetails_datetime) as dates , bu_events.event_daysbeforeType
FROM "bu_events"
INNER JOIN "bu_eventdetails" ON "bu_eventdetails"."event_id" = "bu_events"."event_id"
WHERE "bu_events"."is_active" = 1
AND "bu_events"."is_deleted" =0
AND "bu_eventdetails"."is_active" = 1
AND "bu_eventdetails"."is_deleted" =0
AND "bu_events"."service_id" = '31'
AND (DATEDIFF(Minute, BU_EventDetails.eventDetails_datetime, '2017-07-12 10:33:19') <=0 or coalesce(event_always_available,0) = 1 )
AND
CASE
WHEN bu_events.event_daysbeforeType = 1 THEN
(DATEDIFF(d, '2017-07-12 10:33:19',BU_EventDetails.eventDetails_datetime) >= coalesce(BU_Events.event_daysbefore, 0) or coalesce(event_always_available,0) = 1 )
ELSE
(DATEDIFF(hour, '2017-07-12 10:33:19',BU_EventDetails.eventDetails_datetime) >= coalesce(BU_Events.event_daysbefore, 0) or coalesce(event_always_available,0) = 1 )
END
AND ( select max(availabletable_amount)
from bu_availabletable
inner join bu_eventdetails on bu_eventdetails.eventdetail_id = bu_availabletable.eventdetail_id
inner join bu_eventpricegroups on bu_eventpricegroups.event_id = bu_eventdetails.event_id
where bu_availabletable.eventdetail_id = bu_eventdetails.eventdetail_id
and bu_eventpricegroups.eventpricegroup_always_available = 0 ) > 0
AND datepart(Month,eventdetails_datetime) = 07
AND datediff(d,getdate(),eventdetails_datetime)>=0
Any ideas what i'm doing wrong ?
You can't use case like you this. case is an expression, and you try to use it as flow control.
From MSDN:
The CASE expression cannot be used to control the flow of execution of Transact-SQL statements, statement blocks, user-defined functions, and stored procedures. For a list of control-of-flow methods, see Control-of-Flow Language (Transact-SQL).
Instead of using case, do this:
AND
(
(
bu_events.event_daysbeforeType = 1
AND (DATEDIFF(d, '2017-07-12 10:33:19',BU_EventDetails.eventDetails_datetime) >= coalesce(BU_Events.event_daysbefore, 0) or coalesce(event_always_available,0) = 1 )
)
OR
(
bu_events.event_daysbeforeType <> 1
AND (DATEDIFF(hour, '2017-07-12 10:33:19',BU_EventDetails.eventDetails_datetime) >= coalesce(BU_Events.event_daysbefore, 0) or coalesce(event_always_available,0) = 1 )
)
)
CASE is for computing the value and as SQL has no logical (boolean) values it shouldn't be mixed up with logical expressions but a computed value is a valid argument of logical expression. Try
AND (CASE WHEN bu_events.event_daysbeforeType = 1
THEN (DATEDIFF(d, '2017-07-12 10:33:19',BU_EventDetails.eventDetails_datetime)
ELSE DATEDIFF(hour, '2017-07-12 10:33:19',BU_EventDetails.eventDetails_datetime)
END >= coalesce(BU_Events.event_daysbefore, 0) or coalesce(event_always_available,0) = 1
)
Weird thing happening.
Query below runs less than a second, but if I change anything(like extra space) in WHERE clause then the whole query running 7 seconds.
Or if I comment out one of those lines (SELECT ISNULL(SUM(...) ...
Never see that before...
SELECT...
...
FROM ...
--If I put extra space after SELECT - the whole query running 7 seconds
WHERE EXISTS
(SELECT * FROM tblClaims_ReservePayments RP
WHERE
CASE WHEN #coverageTypeId IS NULL THEN 1
ELSE
CASE WHEN RP.CoverageTypeId = #coverageTypeId THEN 1 ELSE 0 END END = 1
AND (DATEDIFF(d, #dateFrom, RP.DateCreated) >= 0 AND DATEDIFF(d, #dateTo, RP.DateCreated) <= 0) AND RP.ClaimId = C.ClaimId)
AND
CASE WHEN #companyGuid IS NULL THEN 1 ELSE CASE WHEN CPI.CompanyGuid = #companyGuid THEN 1 ELSE 0 END END = 1
AND
EXISTS (SELECT * FROM tblClaims_Claimants CLMNT WHERE CLMNT.ClaimID = C.ClaimID AND CLMNT.StatusId = 0)
AND EXISTS (SELECT * FROM #Adjusters WHERE adjuster = C.InhouseAdjuster)
ORDER BY
CPI.PolicyNumber
What is going on?
Is it parameter sniffing?
The whole statement is below:
DECLARE
#dateFrom DATETIME = '2017-02-01',
#dateTo DATETIME = '2017-05-31',
#companyGuid UNIQUEIDENTIFIER = 'A95645F7-74CF-4551-BD28-5CBC5AD77EF2',-- NULL, Philadelphia
#coverageTypeId INT = NULL,
#inhouseAdjuster varchar(8000) = NULL
DECLARE #Adjusters TABLE(adjuster uniqueidentifier)
IF(#inhouseAdjuster IS NOT NULL AND #inhouseAdjuster <> '')
BEGIN
INSERT INTO #Adjusters
SELECT Guid FROM dbo.StringOfGuidsToTable(#inhouseAdjuster, ',')
END
ELSE
BEGIN
INSERT INTO #Adjusters
SELECT InhouseAdjuster FROM tblClaims_Claim
END
DECLARE #AdjusterString varchar(500)
SET #AdjusterString = ''
DECLARE #CoveringTable TABLE (Covering varchar(1000))
INSERT INTO #CoveringTable
SELECT DISTINCT tblUsers.FirstName + ' ' + tblUsers.LastName FROM tblClaims_Claim
inner join tblUsers on tblUsers.userguid = tblClaims_Claim.userguid
WHERE tblClaims_Claim.InhouseAdjuster IN (SELECT adjuster FROM #Adjusters)
SELECT #AdjusterString = #AdjusterString + CASE WHEN #AdjusterString = '' THEN '' ELSE ', ' END + Covering FROM #CoveringTable
SELECT
CPI.PolicyNumber,
CC.DateReported,--------------------------------------added by Oleg 5/1/2017
C.LossDate as ForfeitureDate,
(SELECT ISNULL(SUM(ResPayAmount), 0) FROM tblClaims_ReservePayments RP INNER JOIN lstClaims_ReservePaymentTypes RPT ON RPT.ResPayTypeId = RP.ResPayTypeId AND RPT.ResPayTypedescription <> 'Expense' WHERE RP.ClaimId = C.ClaimId AND (DATEDIFF(d, #dateFrom, RP.DateCreated) >= 0 AND DATEDIFF(d, #dateTo, RP.DateCreated) <= 0) AND CASE WHEN #coverageTypeId IS NULL THEN 1 ELSE CASE WHEN RP.CoverageTypeId = #coverageTypeId THEN 1 ELSE 0 END END = 1) AS [BondAmount],
dbo.GetEntityName(CPI.InsuredGuid) as Defendant,
CC.UserDef_ClaimantId as CaseNumber,
CC.CorporationName, -----------------------------------------------------------------------------------------------------------------------added by Oleg 5/1/2017
PRIM_ADDRESS.City,-----------------------------------------------------------------------------------------------------------------------added by Oleg 5/1/2017
PRIM_ADDRESS.State,-----------------------------------------------------------------------------------------------------------------------added by Oleg 5/1/2017
PRIM_ADDRESS.County,-----------------------------------------------------------------------------------------------------------------------added by Oleg 5/1/2017
(SELECT ISNULL(SUM(ResPayAmount), 0) FROM tblClaims_ReservePayments RP INNER JOIN lstClaims_ReservePaymentTypes RPT ON RPT.ResPayTypeId = RP.ResPayTypeId AND RPT.ResPayTypedescription <> 'Expense' WHERE RP.ClaimId = C.ClaimId AND IsPayment = 1 AND (DATEDIFF(d, #dateFrom, RP.DateCreated) >= 0 AND DATEDIFF(d, #dateTo, RP.DateCreated) <= 0) AND CASE WHEN #coverageTypeId IS NULL THEN 1 ELSE CASE WHEN RP.CoverageTypeId = #coverageTypeId THEN 1 ELSE 0 END END = 1) AS [ClaimsPaid],
(SELECT ISNULL(SUM(ResPayAmount), 0) FROM tblClaims_ReservePayments RP INNER JOIN lstClaims_ReservePaymentTypes RPT ON RPT.ResPayTypeId = RP.ResPayTypeId AND RPT.ResPayTypedescription <> 'Expense' WHERE RP.ClaimId = C.ClaimId AND IsPayment = 0 AND (DATEDIFF(d, #dateFrom, RP.DateCreated) >= 0 AND DATEDIFF(d, #dateTo, RP.DateCreated) <= 0) AND CASE WHEN #coverageTypeId IS NULL THEN 1 ELSE CASE WHEN RP.CoverageTypeId = #coverageTypeId THEN 1 ELSE 0 END END = 1) AS [ClaimsReserveRemaining],
(SELECT ISNULL(SUM(ResPayAmount), 0) FROM tblClaims_ReservePayments RP INNER JOIN lstClaims_ReservePaymentTypes RPT ON RPT.ResPayTypeId = RP.ResPayTypeId AND RPT.ResPayTypedescription = 'Expense' WHERE RP.ClaimId = C.ClaimId AND (DATEDIFF(d, #dateFrom, RP.DateCreated) >= 0 AND DATEDIFF(d, #dateTo, RP.DateCreated) <= 0)AND CASE WHEN #coverageTypeId IS NULL THEN 1 ELSE CASE WHEN RP.CoverageTypeId = #coverageTypeId THEN 1 ELSE 0 END END = 1) AS [AllocatedReserved],
(SELECT ISNULL(SUM(ResPayAmount), 0) FROM tblClaims_ReservePayments RP INNER JOIN lstClaims_ReservePaymentTypes RPT ON RPT.ResPayTypeId = RP.ResPayTypeId AND RPT.ResPayTypedescription = 'Expense' WHERE RP.ClaimId = C.ClaimId AND IsPayment = 1 AND (DATEDIFF(d, #dateFrom, RP.DateCreated) >= 0 AND DATEDIFF(d, #dateTo, RP.DateCreated) <= 0) AND CASE WHEN #coverageTypeId IS NULL THEN 1 ELSE CASE WHEN RP.CoverageTypeId = #coverageTypeId THEN 1 ELSE 0 END END = 1) AS [AllocatedPaid],
(SELECT ISNULL(SUM(ResPayAmount), 0) FROM tblClaims_ReservePayments RP INNER JOIN lstClaims_ReservePaymentTypes RPT ON RPT.ResPayTypeId = RP.ResPayTypeId AND RPT.ResPayTypedescription = 'Expense' WHERE RP.ClaimId = C.ClaimId AND IsPayment = 0 AND (DATEDIFF(d, #dateFrom, RP.DateCreated) >= 0 AND DATEDIFF(d, #dateTo, RP.DateCreated) <= 0) AND CASE WHEN #coverageTypeId IS NULL THEN 1 ELSE CASE WHEN RP.CoverageTypeId = #coverageTypeId THEN 1 ELSE 0 END END = 1) AS [AllocatedReserveRemaining],
(SELECT ISNULL(SUM(Amount), 0) FROM tblClaims_ClaimExpenses CE WHERE CE.ClaimId = C.ClaimId AND (DATEDIFF(d, #dateFrom, CE.DateEntered) >= 0 AND DATEDIFF(d, #dateTo, CE.DateEntered) <= 0)) AS [UnAllocated]
FROM
tblClaims_Claim C
INNER JOIN
tblClaims_PolicyInformation CPI
ON
CPI.ClaimId = C.ClaimId
INNER JOIN tblClaims_Claimants CC ON C.ClaimId = CC.ClaimId --AND CC.StatusId = 0 -----------------------------------added by Oleg 5/1/2017
INNER JOIN tblClaims_Addresses PRIM_ADDRESS ON PRIM_ADDRESS.AddressId = CC.AddressId ----------------------------------added by Oleg 5/1/2017
CROSS APPLY (SELECT TOP 1 QuoteGUID FROM tblQuotes WHERE tblQuotes.ControlNo = C.ControlNo) t ------------------------added by Oleg 5/1/2017
WHERE EXISTS
(SELECT * FROM tblClaims_ReservePayments RP
WHERE
CASE WHEN #coverageTypeId IS NULL THEN 1
ELSE
CASE WHEN RP.CoverageTypeId = #coverageTypeId THEN 1 ELSE 0 END END = 1
AND (DATEDIFF(d, #dateFrom, RP.DateCreated) >= 0 AND DATEDIFF(d, #dateTo, RP.DateCreated) <= 0) AND RP.ClaimId = C.ClaimId)
AND
CASE WHEN #companyGuid IS NULL THEN 1 ELSE CASE WHEN CPI.CompanyGuid = #companyGuid THEN 1 ELSE 0 END END = 1
AND
EXISTS (SELECT * FROM tblClaims_Claimants CLMNT WHERE CLMNT.ClaimID = C.ClaimID AND CLMNT.StatusId = 0)
AND EXISTS (SELECT * FROM #Adjusters WHERE adjuster = C.InhouseAdjuster)
ORDER BY
CPI.PolicyNumber
UPDATE:
If i put extra space in any line - it changes the performance to 7 sec.
When a query is run, SQL Server compiles it into a query plan.
In order to match the same SQL query to this plan, the database generates a hash code for the query (called a "query hash") based on the query text.
If you change the query in any way-- even seemingly safe things like capitalization (where this does not affect the query), add spaces, add comments-- the query text is now different. SQL Server will generate a different query hash for the query.
Given a new query hash, an existing query plan for this query hash will not be found. Therefore the SQL optimizer will create a new query plan. The new query plan is most likely very different than the old one-- possibly from parameter sniffing, as you suggested.
Commenting out functional parts of the query does actually change the query. For example, commenting out a single line in a SELECT clause can drastically alter the performance of the query, because now SQL Server may not need that column from the table. This means it could select a different index or skip a bookmark lookup, so performance can radically change.
I have a SP that was built for us that does a summary statement of tables in our DB. What I am trying to do is make it so the SP also pulls that last year/month of data as well based on the date entered. Below is the SQL code I am working with. What I am trying to get is a total and Volume field that is the sum based on the date parameter entered minus 1 month.
For example:
If I put in 2013 10 01 start and 2013 10 31 end I would get the total and volume for 2013-10-01 to 2013-10-31 and in 2 separate columns the total and volume for 2013-09-01 to 1013-09-30
Code
(
#Start DATETIME,
#End DATETIME
)
AS
DECLARE
#reference int,
#sSQL VARCHAR(2000)
BEGIN
select Convert(datetime,Cast(edi.Creation_dt as varchar(8)),103) as Date, ia.xref_no_tx, la.ldc_acct_no, la.serv_loc_nm
, a.acct_nm, c.company_last_nm
, Case RG.Rate_cd
When 'DLS' then 'HEDGE'
When 'STL' then 'STL'
WHen 'SPOT BILLING' then 'SPOT'
WHen 'SL SPOT' then 'STL SPOT'
Else null
End as Acct_type
, Convert(datetime,Cast(ia.start_dt as varchar(8)),103)as Start_dt
, Convert(datetime,Cast(ia.end_dt as varchar(8)),103) as End_dt
, edi.trans_sub_ty as Inv_type
, max( case when la.class_ty_cd = 'COMM' and th.ppa_in = 'N' and th.trans_sub_ty_cd = 'FEES' then th.trans_qty
when la.class_ty_cd = 'MUNI' and th.ppa_in = 'N' and th.trans_sub_ty_cd = 'EXCS' then th.trans_qty
when la.class_ty_cd <> 'COMM' and th.ppa_in = 'N' and th.trans_sub_ty_cd = 'BASE' then th.trans_qty
else 0 end) as Volume
, sum(th.trans_am) as Total
from invoice_advise_relate iar, transaction_history th
,invoice_advise ia, ldc_account la, account a, customer c, edi_transaction edi
, (select max(edi_trans_id) as m_edi_trans, relate_id from edi_transaction where class_nm = 'cInvoiceAdvise' group by relate_id) as edic
, (Select max(rating_group_id) as m_rate, ldc_acct_id from rating_group group by ldc_acct_Id) as C_Rate
, rating_group rg
where iar.trans_id = th.trans_id
and th.cancel_in = 'N'
and th.trans_ty_cd not in ('PAY', 'ANC')
and iar.inv_adv_id = ia.inv_adv_id
and ia.ldc_acct_id = la.ldc_acct_id
and la.acct_id = a.acct_id
and a.cust_id = c.cust_id
and la.ldc_acct_no not like 'E%'
and edi.Creation_dt >= convert(varchar,#Start,112)
and edi.Creation_dt <= convert(varchar,#End,112)
and edi.relate_id = ia.inv_adv_id
and edic.m_edi_trans = edi.edi_trans_id
and edi.response_cd = ''
and rg.rating_group_id = C_Rate.M_Rate
and C_Rate.LDC_Acct_Id = la.ldc_Acct_Id
and edi.trans_sub_ty <> '00'
group by edi.Creation_dt, ia.xref_no_tx, la.ldc_acct_no,la.serv_loc_nm, a.acct_nm, c.company_last_nm, ia.start_dt, ia.end_dt,edi.trans_sub_ty, rg.rate_cd
Start off by declaring and initializing a start date for the previous month.
DECLARE #PrevStart datetime
SELECT #PrevStart = dateadd(month, -1, #Start)
In your WHERE clause substitute the previous start date for start date so that you include last month's data as well as this month's.
and edi.Creation_dt >= convert(varchar,#PrevStart,112)
and edi.Creation_dt <= convert(varchar,#End,112)
Then you filter last month's data from this month's using CASE statement logic.
, max( case when la.class_ty_cd = 'COMM' and th.ppa_in = 'N' and th.trans_sub_ty_cd = 'FEES'
AND edi.Creation_dt >= convert(varchar,#Start,112) then th.trans_qty
when la.class_ty_cd = 'MUNI' and th.ppa_in = 'N' and th.trans_sub_ty_cd = 'EXCS'
AND edi.Creation_dt >= convert(varchar,#Start,112) then th.trans_qty
when la.class_ty_cd <> 'COMM' and th.ppa_in = 'N' and th.trans_sub_ty_cd = 'BASE'
AND edi.Creation_dt >= convert(varchar,#Start,112) then th.trans_qty
else 0 end) as Volume
, sum(CASE WHEN edi.Creation_dt >= convert(varchar,#Start,112) THEN th.trans_am ELSE 0 END) as Total
, max( case when la.class_ty_cd = 'COMM' and th.ppa_in = 'N' and th.trans_sub_ty_cd = 'FEES'
AND edi.Creation_dt < convert(varchar,#Start,112) then th.trans_qty
when la.class_ty_cd = 'MUNI' and th.ppa_in = 'N' and th.trans_sub_ty_cd = 'EXCS'
AND edi.Creation_dt < convert(varchar,#Start,112) then th.trans_qty
when la.class_ty_cd <> 'COMM' and th.ppa_in = 'N' and th.trans_sub_ty_cd = 'BASE'
AND edi.Creation_dt < convert(varchar,#Start,112) then th.trans_qty
else 0 end) as PrevVolume
, sum(CASE WHEN edi.Creation_dt < convert(varchar,#Start,112) THEN th.trans_am ELSE 0 END) as PrevTotal