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
)
Related
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')
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
Im having a problem with this :( is this because of my select statement? or any join? derived table? or my CASE syntax?
The error occurs the time I put this CASE syntax: CASE WHEN dbo.AdditionalInfo.UserDefined3 = 1 THEN 2
because before it is just:
CASE WHEN WorkOrder.DateCreated < (CASE WHEN (DATEPART(dw,
dbo.ToBeScheduled_InProgress.Start) = 2) THEN (ToBeScheduled_InProgress.Start + 0.625) - 3 ELSE (ToBeScheduled_InProgress.Start + 0.625) - 1 END) THEN 1 ELSE 2 END AS ScheduleTime
SELECT Start, UserDefined3, ItemNo, Name, TotalQtyRequired, PreviouslyCounted, QtyLeftToPick, LocationCode, Location, Rack, QtyInRack, PickQty, CellCode, UDMaterial, UDMaterialSort, ScheduleTimeFROM (SELECT dbo.ToBeScheduled_InProgress.Start, dbo.ItemSpecs.ItemNo, dbo.ItemSpecs.Name, SUM(ISNULL(dbo.ToBeScheduled_InProgress.RemainingQty, 0) * ISNULL(dbo.ItemSpecFullStruc.TotalQtyPerRoot, 0))
AS TotalQtyRequired, ISNULL(RackedInventory.PreviouslyCounted, 0) AS PreviouslyCounted, SUM(ISNULL(dbo.ToBeScheduled_InProgress.RemainingQty, 0) * ISNULL(dbo.ItemSpecFullStruc.TotalQtyPerRoot, 0))
- ISNULL(RackedInventory.PreviouslyCounted, 0) AS QtyLeftToPick, RackedInventory.LocationCode, RackedInventory.Location, RackedInventory.Rack, ISNULL(RackedInventory.QtyInRack, 0) AS QtyInRack,
ISNULL(CASE WHEN SUM(ISNULL(dbo.ToBeScheduled_InProgress.RemainingQty, 0) * ISNULL(dbo.ItemSpecFullStruc.TotalQtyPerRoot, 0)) - ISNULL(RackedInventory.PreviouslyCounted, 0)
< RackedInventory.QtyInRack THEN SUM(ISNULL(dbo.ToBeScheduled_InProgress.RemainingQty, 0) * ISNULL(dbo.ItemSpecFullStruc.TotalQtyPerRoot, 0)) - ISNULL(RackedInventory.PreviouslyCounted, 0)
ELSE RackedInventory.QtyInRack END, 0) AS PickQty, dbo.ToBeScheduled_InProgress.CellCode, dbo.ItemSpecs.Userdefined2 AS UDMaterial, CASE WHEN dbo.ItemSpecs.Userdefined2 IN ('Foam', 'Wood',
'Plastic Inner', 'Rubber') THEN 0 ELSE 1 END AS UDMaterialSort, CASE WHEN dbo.AdditionalInfo.UserDefined3 = 1 THEN 2 WHEN WorkOrder.DateCreated < (CASE WHEN (DATEPART(dw,
dbo.ToBeScheduled_InProgress.Start) = 2) THEN (ToBeScheduled_InProgress.Start + 0.625) - 3 ELSE (ToBeScheduled_InProgress.Start + 0.625) - 1 END) THEN 1 ELSE 2 END AS ScheduleTime
FROM dbo.ToBeScheduled_InProgress INNER JOIN
dbo.OpenCalendarDaysTable AS OpenCalendarDays ON dbo.ToBeScheduled_InProgress.Start BETWEEN OpenCalendarDays.CalendarDateForwardRangeStart AND
OpenCalendarDays.CalendarDateForwardRangeEnd AND OpenCalendarDays.CalendarLinkID IS NULL INNER JOIN
dbo.OpenCalendarDaysTable AS PriorOpenCalendarDays ON OpenCalendarDays.CalendarOpenDayID = PriorOpenCalendarDays.CalendarOpenDayID + 1 AND OpenCalendarDays.CalendarLinkID IS NULL
INNER JOIN
dbo.ItemSpecFullStruc ON dbo.ToBeScheduled_InProgress.ItemSpecID = dbo.ItemSpecFullStruc.RootItemSpecID INNER JOIN
dbo.ItemSpecs ON dbo.ItemSpecFullStruc.ChildItemSpecID = dbo.ItemSpecs.ItemSpecID LEFT OUTER JOIN
dbo.WorkOrder ON dbo.ToBeScheduled_InProgress.WorkOrderID = dbo.WorkOrder.WorkOrderID LEFT OUTER JOIN
(SELECT InventoryByLocation.ItemID, InventoryByLocation.ItemNo, InventoryByLocation.ItemDescription, InventoryByLocation.LocationCode, InventoryByLocation.Location, InventoryByLocation.Rack,
InventoryByLocation.QtyInRack, SUM(PreviouslyCounted.QtyInRack) AS PreviouslyCounted
FROM (SELECT Rack, SUM(ISNULL(QtyToStock, ' ')) AS QtyInRack, ItemID, ItemSpecID, LocationID
FROM dbo.InventoryItems WITH (NOLOCK)
GROUP BY ItemID, ItemSpecID, LocationID, Rack) AS PreviouslyCounted RIGHT OUTER JOIN
(SELECT Items_1.ItemNo, Items_1.Name AS ItemDescription, Locations_1.LocationCode, Locations_1.DescriptionMed AS Location, InventoryItems_1.Rack,
SUM(dbo.Val(ISNULL(InventoryItems_1.QtyToStock, ''))) AS QtyInRack, UOMs_1.UOMCode AS StockUOM, InventoryItems_1.ItemID, InventoryItems_1.ItemSpecID,
Locations_1.LocationID
FROM dbo.Items AS Items_1 WITH (NOLOCK) INNER JOIN
dbo.Locations AS Locations_1 WITH (NOLOCK) INNER JOIN
dbo.InventoryItems AS InventoryItems_1 WITH (NOLOCK) LEFT OUTER JOIN
dbo.UOMs AS UOMs_1 WITH (NOLOCK) ON InventoryItems_1.StockUOMID = UOMs_1.UOMID ON Locations_1.LocationID = InventoryItems_1.LocationID ON
Items_1.ItemID = InventoryItems_1.ItemID
WHERE (Locations_1.LocationID = 7)
GROUP BY Locations_1.LocationCode, Items_1.ItemNo, Locations_1.DescriptionMed, Items_1.Name, UOMs_1.UOMCode, InventoryItems_1.ItemID, InventoryItems_1.ItemSpecID,
Locations_1.LocationID, InventoryItems_1.Rack
HAVING (SUM(dbo.Val(ISNULL(InventoryItems_1.QtyToStock, ''))) > 0)) AS InventoryByLocation ON PreviouslyCounted.Rack < InventoryByLocation.Rack AND
PreviouslyCounted.LocationID = InventoryByLocation.LocationID AND PreviouslyCounted.ItemID = InventoryByLocation.ItemID
GROUP BY InventoryByLocation.ItemNo, InventoryByLocation.ItemDescription, InventoryByLocation.LocationCode, InventoryByLocation.Location, InventoryByLocation.Rack, InventoryByLocation.QtyInRack,
InventoryByLocation.ItemID) AS RackedInventory ON dbo.ItemSpecs.ItemID = RackedInventory.ItemID
WHERE (dbo.ToBeScheduled_InProgress.ExcludeFromFiniteScheduling = 0) AND (ISNULL(dbo.ItemSpecs.Userdefined2, '') <> 'Covering') AND (dbo.ItemSpecs.InventoryTrackingID > 1)
GROUP BY dbo.ToBeScheduled_InProgress.Start, dbo.ItemSpecs.ItemNo, dbo.ItemSpecs.Name, RackedInventory.Rack, ISNULL(RackedInventory.PreviouslyCounted, 0), RackedInventory.Location,
RackedInventory.LocationCode, dbo.ToBeScheduled_InProgress.CellCode, dbo.ItemSpecs.Userdefined2,
CASE WHEN dbo.AdditionalInfo.UserDefined3 = 1 THEN 2 WHEN WorkOrder.DateCreated < (CASE WHEN (DATEPART(dw, dbo.ToBeScheduled_InProgress.Start) = 2) THEN (ToBeScheduled_InProgress.Start + 0.625)
- 3 ELSE (ToBeScheduled_InProgress.Start + 0.625) - 1 END) THEN 1 ELSE 2 END, RackedInventory.QtyInRack
HAVING (SUM(ISNULL(dbo.ToBeScheduled_InProgress.RemainingQty, 0) * ISNULL(dbo.ItemSpecFullStruc.TotalQtyPerRoot, 0)) - ISNULL(RackedInventory.PreviouslyCounted, 0) > 0)) AS _RackSort_Lean_AMPM ORDER BY Start, LocationCode, Rack
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.
the below SQL statement generates a pivot table, all of which is working correctly. However, at the bottom of the code, I am trying to display values from another table (availabilitynotes) - in this example below the note would be "A/P". Each single day will have either 0 or 1 notes on the individual day. When a note is present, the note is displayed. When no note is present, the COALESCE value is displayed. However, when a note for 1 teacher is set on a monday and one on a wednesday, a duplicate row is returned. How can I set it to return all values on one single row?
WITH Bookings AS
( SELECT TeacherID,
[WeekDay] = DATENAME(WEEKDAY, BookingDate),
[Status] = CASE WHEN [2] > 0 THEN 'XXX'
WHEN [0] > 0 AND [1] > 0 THEN 'XXX'
WHEN [0] > 0 THEN 'PM'
WHEN [1] > 0 THEN 'AM'
WHEN [3] > 0 AND CONVERT(time(0), EndTime) <= CONVERT(time(0), '12:00:00') and CONVERT(time(0), StartTime) < CONVERT(time(0), '12:00:00') THEN 'PM'
WHEN [3] > 0 AND CONVERT(time(0), StartTime) >= CONVERT(time(0), '12:00:00') THEN 'AM'
WHEN [3] > 0 AND CONVERT(time(0), StartTime) <= CONVERT(time(0), '12:00:00') AND CONVERT(time(0), EndTime) >= CONVERT(time(0), '12:00:00') THEN 'XXX'
END
FROM ( SELECT TeacherID, BookingDate, BookingDuration, StartTime, EndTime, [X] = 1
FROM BookingDays where (Status = 0 or Status IS NULL)
) BookingDays
PIVOT
( SUM(X)
FOR BookingDuration IN ([0], [1], [2], [3])
) pvt
WHERE BookingDate >= DATEADD(ww, DATEDIFF(ww,0,#Date), 0) AND BookingDate <= DATEADD(ww, DATEDIFF(ww,0,#Date), 6)
), PivotedBookings AS
( SELECT *
FROM Bookings
PIVOT
( MAX([Status])
FOR [WeekDay] IN ([Monday], [Tuesday], [Wednesday], [Thursday], [Friday])
) pvt
)
SELECT t.ID,
t.Firstname,
t.Surname,
CASE WHEN t.Nursery > 0 THEN 'NUR' WHEN t.Reception > 0 THEN 'REC' WHEN t.Year1 > 0 THEN 'Y1' WHEN t.Year2 > 0 THEN 'Y2' WHEN t.Year3 > 0 THEN 'Y3' WHEN t.Year4 > 0 THEN 'Y4' WHEN t.Year5 > 0 THEN 'Y5' WHEN t.Year6 > 0 THEN 'Y6' WHEN t.Year7 > 0 THEN 'Y7' WHEN t.Year8 > 0 THEN 'Y8' WHEN t.Year9 > 0 THEN 'Y9' WHEN t.Year10 > 0 THEN 'Y10' WHEN t.Year11 > 0 THEN 'Y11' WHEN t.ALevel > 0 THEN 'ALevel' END + ' - ' + CASE WHEN t.ALevel > 0 THEN 'ALevel' WHEN t.Year11 > 0 THEN 'Y11' WHEN t.Year10 > 0 THEN 'Y10' WHEN t.Year9 > 0 THEN 'Y9' WHEN t.Year8 > 0 THEN 'Y7' WHEN t.Year6 > 0 THEN 'Y6' WHEN t.Year5 > 0 THEN 'Y6' WHEN t.Year4 > 0 THEN 'Y4' WHEN t.Year3 > 0 THEN 'Y3' WHEN t.Year2 > 0 THEN 'Y2' WHEN t.Year1 > 0 THEN 'Y1' WHEN t.Reception > 0 THEN 'REC' WHEN t.Nursery > 0 THEN 'NUR' ELSE '' END as 'KeyStage',
Monday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,#Date), 0) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.Monday, '') END,
Tuesday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,#Date), 1) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.Tuesday, '') END,
Wednesday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,#Date), 2) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.Wednesday, '') END,
Thursday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,#Date), 3) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.Thursday, '') END,
Friday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,#Date), 4) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.Friday, '') END
FROM Teachers t
LEFT JOIN PivotedBookings pb
ON pb.TeacherID = t.ID
LEFT JOIN TeacherBands tb
ON tb.ID = t.Band
LEFT JOIN AvailabilityNotes an
ON t.ID = an.TeacherID
WHERE t.Active = 0 and (t.Status = 1 or t.Status = 0) and t.PrimarySchool = 1
ORDER BY t.Surname, t.Firstname asc
This generates the following output -
ID | Firstname | Surname | Mon | Tue | Wed | Thu | Fri
1 Steve Smith XXX PM AM A/P NULL
1 Steve Smith XXX PM AM NULL A/P
When I need it to be -
ID | Firstname | Surname | Mon | Tue | Wed | Thu | Fri
1 Steve Smith XXX PM AM A/P A/P
Thanks
You need the valid value for each day, which will be greater than NULL if extant.
select ID, Firstname, Surname
, max(Monday) as Monday, -- etc
from ( your giant query ) as Q
group by ID, Firstname, Surname
should do the trick.