我可以缩短这个SQL查询吗?

时间:2014-02-03 11:21:13

标签: sql sql-server sql-server-2008

我已经编写了一个查询来获取过去5个月没有活动的总数分配,包括五个月前创建的从未对其进行任何访问的分配。

我可以进一步缩短此查询,因此我不必使用外部查询。

  SELECT @NumNoActivity = COUNT(QnoActivity.AssignmentID) FROM

  (

    SELECT a.AssignmentID
    FROM Assignments a
    LEFT JOIN VISITS v ON v.AssignmentID = a.AssignmentID
    WHERE a.CurrentStatus = 1  
    AND a.StaffID = @StaffID
    GROUP BY a.AssignmentID,  a.CreatedDate
    HAVING DATEDIFF(MONTH, ISNULL(MAX(v.VisitDate),a.CreatedDate ), GETDATE())  > =5

  ) QnoActivity

2 个答案:

答案 0 :(得分:2)

您可以使用NOT EXISTS删除联接:

SELECT @NumNoActivity = COUNT(a.AssignmentID)
FROM Assignments a
WHERE a.CurrentStatus = 1  
AND a.StaffID = @StaffID
AND NOT EXISTS
        (SELECT * FROM VISITS v 
         WHERE v.AssignmentID = a.AssignmentID
         AND v.VisitDate>DATEADD(month,-5,GETDATE()))

<强>更新

根据Gordon Linoff的评论,该查询缺少Assignments.CreatedDate条件。这是一个更新版本:

SELECT @NumNoActivity = COUNT(a.AssignmentID)
FROM Assignments a
WHERE a.CurrentStatus = 1  
AND a.StaffID = @StaffID
AND (SELECT ISNULL(MAX(VisitDate), a.CreatedDate) FROM VISITS v 
         WHERE v.AssignmentID = a.AssignmentID) <= DATEADD(month,-5,GETDATE())

以下SQL Fiddle显示其工作原理。作业结果如下:

  • 1 - 不包括在内,因为最近有一次访问
  • 2 - 包括因为没有访问且创建日期旧
  • 3 - 包括因为最近只有一次访问
  • 4 - 不包括在内,因为没有访问但是创建日期是最近的
  • 5 - 不包括在内,因为最近有一次访问

答案 1 :(得分:1)

还有另一种方法可以编写此查询。您可以将其视为“作业”总数与过去4/5个月内有活动的“作业”总数之间的差异。

以下采用这种方法。它排除where子句中的新“赋值”,并计算select子句中的不同:

SELECT (count(distinct a.AssignmentID) -
        count(distinct case when datediff(MONTH, v.VisitDate, GETDATE()) < 5 or
                                 v.VisitDate is null
                            then a.AssignmentId end)
       )
FROM Assignments a LEFT JOIN
     VISITS v
     ON v.AssignmentID = a.AssignmentID
WHERE a.CurrentStatus = 1 AND
      a.StaffID = @StaffID and
      a.CreatedDate <= DATEADD(month, -5, GETDATE());