I have the following query:
SELECT dlp.ParamID ParamID, dp.ParamName ParamName, dlp.LocID LocationID, ml.LocName LocationName , di.Entered_On DateEntered, dlp.FreqDays Frequency
FROM data_LocParams dlp
INNER JOIN data_Input di on dlp.LocID = di.LocID
INNER JOIN data_Parameters dp on dp.ParamID = di.ParamID
INNER JOIN map_Locations ml on ml.LocId = dlp.LocId
WHERE ( (dlp.FreqDays IS NOT NULL) AND di.Entered_On < (GETUTCDATE() - dlp.FreqDays))
AND
di.Entered_On = (select max(Entered_On ) from data_Input where LocId = dlp.LocID
and ParamId = dlp.ParamID)
I need assistance on how to optimize this query. The bottleneck seems to be with the followng:
di.Entered_On = (select max(Entered_On ) from data_Input where LocId = dlp.LocID
and ParamId = dlp.ParamID)
Note that for a given Enter_On, I need to get the Max Entered_On date based on LocId and ParamId.
I tried the following but did not get the intended result:
SELECT * FROM
(
SELECT dlp.ParamID ParamID, dp.ParamName ParamName, dlp.LocID LocationID, ml.LocName LocationName, di.Entered_On DateEntered, dlp.FreqDays Frequency,
ROW_NUMBER() OVER (PARTITION BY dlp.LocId, dlp.ParamID
ORDER BY di.Entered_On DESC)
as RowNum
FROM data_LocParams dlp
INNER JOIN data_Input di on dlp.LocID = di.LocID
INNER JOIN data_Parameters dp on dp.ParamID = di.ParamID
INNER JOIN map_Locations ml on ml.LocId = dlp.LocId
WHERE dlp.FreqDays IS NOT NULL
) as a WHERE a.RowNum = 1 and DateEntered < (GETUTCDATE() - Frequency)
I think you can replace it with a window function on the di
table (done here as a subquery). Note that the where
clause is not in the subquery, because that effects the rows used for the max()
(this is probably the problem in your second query):
SELECT dlp.ParamID ParamID, dp.ParamName ParamName, dlp.LocID LocationID, ml.LocName LocationName , di.Entered_On DateEntered, dlp.FreqDays Frequency
FROM data_LocParams dlp
INNER JOIN (select di.*,
max(Entered_On) over (partition by LocId, ParamId) as maxeo
from data_Input di
) di on dlp.LocID = di.LocID
INNER JOIN data_Parameters dp on dp.ParamID = di.ParamID
INNER JOIN map_Locations ml on ml.LocId = dlp.LocId
WHERE (dlp.FreqDays IS NOT NULL) AND di.Entered_On = di.maxeo and
di.Entered_On < (GETUTCDATE() - dlp.FreqDays)
Try using like this -
select ParamID,
ParamName,
LocationID,
LocationName,
DateEntered,
Frequency
from (SELECT dlp.ParamID ParamID,
dp.ParamName ParamName,
dlp.LocID LocationID,
ml.LocName LocationName,
di.Entered_On DateEntered,
dlp.FreqDays Frequency,
row_number() over(partition by di.LocID order by di.Entered_On desc) as rn
FROM data_LocParams dlp
INNER JOIN data_Input di ON dlp.LocID = di.LocID
INNER JOIN data_Parameters dp ON dp.ParamID = di.ParamID
INNER JOIN map_Locations ml ON ml.LocId = dlp.LocId
WHERE ((dlp.FreqDays IS NOT NULL) AND di.Entered_On < (GETUTCDATE() - dlp.FreqDays))
) as T
where rn = 1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.