Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server 2008:WHERE子句中的CASE语句和短路查询_Sql_Sql Server 2008_Case - Fatal编程技术网

SQL Server 2008:WHERE子句中的CASE语句和短路查询

SQL Server 2008:WHERE子句中的CASE语句和短路查询,sql,sql-server-2008,case,Sql,Sql Server 2008,Case,我试图使这个查询在一个过程中工作 现在,它会过滤掉状态6和状态8中早于保留期的数据。还有其他身份。我想确保保留逻辑仅适用于6,8中的状态,而不适用于其他类型的状态。此过程不会返回其他状态的数据。我是否可以将查询缩短为仅针对6和8状态运行,并返回除6和8之外的其他状态的数据 DECLARE @ReportRetentionPeriod INT = 0 SELECT @ReportRetentionPeriod = [PropertyValue] FROM [CQM].[dbo].[CompanyP

我试图使这个查询在一个过程中工作

现在,它会过滤掉状态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语句,是因为我必须使用不同的日期来比较不同的状态。

几乎每次在where子句中使用case时,您都走错了路。此外,您需要特别声明,如果QS.[Id]不是6或8,则不需要其他标准。如前所述,当QS.[Id]不是6或8时,代码计算GETDATE-@ReportRetentionPeriod
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))

您可以添加一个具有固定日期的ELSE,该日期将保证大于GETDATE-@ReportRetentionPeriod。两件事:1为什么要运行转换?日期是否未存储为日期?2请不要使用诸如GETDATE之类的速记-一些数字-这与某些日期/时间类型有关。请阅读和。另外,由于语义很重要,所以只是对命名法的一点挑剔:。也许有RF.Id在场,您可以做些什么?当JD和RF都存在而只有JD存在时,你是想说这样做吗?谢谢@AaronBertrand。是的,它应该是大小写表达式。而且,我不能在其他地方使用固定日期。是的,我不认为我需要转换,因为那些列已经是datetime了。这是什么意思?如果你想让ID不在6,8中的比较总是返回true,那么你可以说ELSE'9999-12-31'。你的原始代码对我有用。编辑看起来更干净,我必须尝试一下?现在就可以了,但是我们还需要转换吗?因为CREATEDON已经是DATETIME了。可能不是。我无法知道CREATEDON是什么数据类型,所以我留下了转换,因为它在原始代码中。
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))