我正在尝试在过程工作中进行此查询。
现在它过滤掉状态6和8的保留期之前的数据。还有其他状态。我想确保保留逻辑仅适用于(6,8)中的状态而不适用于其他类型的状态。此过程不会返回其他状态的数据。我可以将查询短路只运行6和8状态并返回6和8以外的状态数据吗?
DECLARE @ReportRetentionPeriod INT = 0
SELECT @ReportRetentionPeriod = [PropertyValue] FROM [CQM].[dbo].[CompanyProperties] WHERE [PropertyName] = 'ReportRetentionPeriod'
SELECT
DISTINCT
JD.[Id] AS JobDetailId
,JD.[EntityId]
,JD.[QueueStatusId] AS QueueStatus
,RF.[FileName]
,RF.[CreatedOn] AS GeneratedOn
,QS.[Name] AS QueueStatusName
FROM [dbo].[JobDetail] JD
INNER JOIN [dbo].[QueueStatus] AS QS ON QS.[Id] = JD.[QueueStatusId]
LEFT JOIN [dbo].[ReportFile] RF ON RF.[Id] = JD.[FileId]
WHERE JD.JobId = 1234
-- Added codition to use file createdon for completed jobs and job detail createdon for error'd jobs
AND ((GETDATE() - @ReportRetentionPeriod) < CASE QS.[Id]
WHEN 6 THEN
CONVERT(DATETIME, RF.[CREATEDON], 101)
WHEN 8 THEN
CONVERT(DATETIME, JD.[CreatedOn], 101)
END)
使用case语句,因为我必须使用不同的日期来比较不同的状态。
答案 0 :(得分:1)
几乎每当你在case
条款中使用where
时,你就走错了路。此外,您需要明确声明如果QS.[Id]
不是6或8,则不需要其他标准。如上所述,当QS.[Id]
不是6或8时,您的代码会评估(GETDATE() - @ReportRetentionPeriod) < NULL
。你的where子句应该是:
WHERE JD.JobId = 1234
AND (( QS.[Id] = 6 and DATEADD(DAY, -1*ReportRetentionPeriod, GETDATE())
< CONVERT(DATETIME, RF.[CREATEDON], 101))
OR (QS.[Id] = 8 and DATEADD(DAY, -1*ReportRetentionPeriod, GETDATE())
< CONVERT(DATETIME, JD.[CreatedOn], 101))
OR QS.[Id] not in (6,8))
虽然最终会持续一段时间,但它的表现会更好,因为优化程序在解释and
/ or
构造时会有比解释时更多的选项case
。
如果是我,我可能还会将日期逻辑放在您获得保留期的行中,而不是在评估时:
DECLARE @ReportRetentionDate DATETIME
SELECT @ReportRetentionDate = DATEADD(DAY, -1*[PropertyValue], GETDATE())
FROM [CQM].[dbo].[CompanyProperties]
WHERE [PropertyName] = 'ReportRetentionPeriod'
SELECT
DISTINCT
JD.[Id] AS JobDetailId
,JD.[EntityId]
,JD.[QueueStatusId] AS QueueStatus
,RF.[FileName]
,RF.[CreatedOn] AS GeneratedOn
,QS.[Name] AS QueueStatusName
FROM [dbo].[JobDetail] JD
INNER JOIN [dbo].[QueueStatus] AS QS ON QS.[Id] = JD.[QueueStatusId]
LEFT JOIN [dbo].[ReportFile] RF ON RF.[Id] = JD.[FileId]
WHERE JD.JobId = 1234
AND (( QS.[Id] = 6 and @ReportRetentionDate < CONVERT(DATETIME, RF.[CREATEDON], 101))
OR (QS.[Id] = 8 and @ReportRetentionDate < CONVERT(DATETIME, JD.[CreatedOn], 101))
OR QS.[Id] not in (6,8))