使用Max with CTE和CASE T-SQL

时间:2018-03-27 13:14:42

标签: sql-server tsql stored-procedures max common-table-expression

我正在尝试使用MAX()选择数据库中最近的展示位置日期,然后使用Table_CTE,以便我可以在所需日期之间进行选择和过滤。

BEGIN
    DECLARE @Rangetill DATE, @Rangefrom DATE

    SET @rangefrom = DATEADD(day, -50, GETDATE()) 
    SET @Rangetill = DATEADD(day, -90, GETDATE());

    WITH Table_CTE (Name, ID, Rangefrom, Rangetill, StatusID, Statusdate) AS 
    (
        SELECT
            PE.Personname + ' ' + PE.Surname [Name],
            A.ApplicantId,
            @rangefrom [Expiry warning from],
            @rangetill [Expiry warning till],
            A.Statusid,
            selected = CASE 
                          WHEN P.EndDate IS NOT NULL AND P.EndDate > A.StatusDate
                             THEN CONVERT(DATE, P.EndDate, 103) 
                             ELSE CONVERT(DATE, A.StatusDate, 103)
                       END
        FROM
            Applicants AS A 
        LEFT JOIN 
            Person AS PE ON A.ApplicantId = PE.PersonID
        LEFT JOIN 
            Placements AS P on A.applicantid = P.Applicantid
    )
    SELECT * 
    FROM Table_CTE
    WHERE table_cte.Statusdate BETWEEN @Rangetill AND @Rangefrom
      AND (Table_CTE.StatusID = 58 OR Table_CTE.statusid = 63)
    ORDER BY Name DESC
END

以上选择正确的信息,但也选择具有展示位置结束日期(p.enddate)的重复申请人,因为它们可能已多次放置。 WHERE子句还将最近的enddate限制在Variables提供的范围内,因为需要有一个日志,所以会有多个结束日期。所以我的解决方案或想法是在Case或CTE Select中使用max()。但是我不确定在这种情况下如何使用或使用Max()。

在这种情况下,我想检查并返回Max(p.enddate)(如果存在)并将其存储在Table_CTE的状态日期中。

这是否可行,是否是在存储过程中提供此信息的最佳方式?

2 个答案:

答案 0 :(得分:0)

在CTE中会更有效但这更容易

SELECT c.[Name], max(c.Statusdate)
FROM Table_CTE c
WHERE c.Statusdate Between @Rangetill and @Rangefrom
  AND c.StatusID in (58, 63)
group by c.[Name] 

自己添加其他列

答案 1 :(得分:0)

    Declare 

@Rangetill date,
@Rangefrom date

SET @rangefrom = DATEADD(day, -50, GETDATE()) 
SET @Rangetill = DATEADD(day, -90, GETDATE());


With Table_CTE ( ID, Rangefrom, Rangetill, Statusdate)
AS (
Select 
  A.ApplicantId
, @rangefrom [Expiry warning from]
, @rangetill [Expiry warning till]
, selected = CASE 
        WHEN max(P.EndDate) IS NOT NULL AND max(P.EndDate) > max(A.StatusDate)
        THEN  max(CONVERT(DATE, P.EndDate, 103))

        ELSE max(CONVERT(DATE, A.StatusDate, 103))
END


FROM       Applicants AS A 
LEFT JOIN Person AS PE ON A.ApplicantId = PE.PersonID
LEFT JOIN Placements AS P on A.applicantid = P.Applicantid

GROUP BY A.ApplicantId

)

SELECT 
  PE.PersonName + ' ' + PE.Surname [NAME]
, A.ApplicantId 
, Table_CTE.ID
, Table_CTE.Statusdate
, @Rangefrom [Range from]
, @Rangetill [Range till]


FROM Table_CTE
LEFT JOIN Applicants AS A ON A.ApplicantId = Table_CTE.ID
LEFT JOIN Person as PE on PE.PersonID = A.ApplicantId
WHERE  table_cte.Statusdate Between @Rangetill and @Rangefrom
AND (A.StatusID = 58 or A.statusid = 63 )


Order by PE.PersonName + ' '+ PE.Surname desc
END

对于事情来说真的很乱,但是我通过从CTE中移除除变量和ID以外的所有内容来获得我的解决方案,因此我可以在A.statusdate和P.EndDate上选择Max(DATE)。

通过这样做,我可以通过A.ApplicantID进行分组并重新加入CTE之外的特定表格,以便将申请人姓名和状态ID返回到我的结果集中。

感谢大家的帮助。