待处理的每月 SQL 计数

Pending Monthly SQL Counts

下面的查询 returns 准确的信息,我只是没有运气尝试做到这一点:

1) 更加动态,所以我不会每个月都重复同一行代码

2) 格式不同,因此只需 2 列月 + 年即可按 field1 + field2 查看待处理计数

示例代码(基本上,当(OPEN 日期是 before/on 该月的最后一天)和(CLOSE 日期在该月之后或者它仍然打开)

SELECT
SUM(CAST(case when OPENDATE <= '2014-11-30 23:59:59' 
      and ((CLOSED >= '2014-12-01')  
            or (CLOSED is null)) then '1' else '0' end as int)) Nov14    
,SUM(CAST(case when OPENDATE <= '2014-12-31 23:59:59'
      and ((CLOSED >= '2015-01-01')  
            or (CLOSED is null)) then '1' else '0' end as int)) Dec14          
,SUM(CAST(case when OPENDATE <= '2015-01-30 23:59:59'
      and ((CLOSED >= '2015-02-01')  
            or (CLOSED is null)) then '1' else '0' end as int)) Jan15 
,FIELD1,FIELD2 
FROM T 
GROUP BY FIELD1,FIELD2

结果:

FIELD1 FIELD2 NOV14  DEC14  JAN15
A      A      2      5      7
A      B      6      8      4
C      A      5      6      5

而不是:

COUNT   FIELD1 FIELD2  MO   YR
14      A      A       12   2014      
18      A      B       12   2014             
16      C      A       1    2015    

...

有没有办法一次搞定?抱歉,如果这是一个重复的话题,我看过一些看板,它们帮助我获得了结束计数……但是使用两个日期字段之间的范围,我没有任何运气。

提前致谢

像这样:

SELECT
FIELD1,FIELD2,datepart(month, OPENDATE), datepart(year, OPENDATE), sum(1)
FROM T 
GROUP BY FIELD1,FIELD2, datepart(month, OPENDATE), datepart(year, OPENDATE)

但这当然只是基于 OPENDATE,如果您需要将同一件事计算到几个月内,那将更加困难,您可能需要一个日历 "table" '必须交叉应用此数据。

一种方法是使用 table of numbers or calendar table。 在下面的代码中 table Numbers 有一列 Number,其中包含从 1 开始的整数。generate such table 有很多方法。 您可以即时进行,也可以使用实际的 table。我个人在数据库中有这样的 table,有 100,000 行。

第一个 CROSS APPLY 有效地创建了一个列 CurrentMonth,这样我以后就不必多次重复调用 DATEADD

第二个 CROSS APPLY 是您希望每个月 运行 的查询。它可以根据需要复杂化,如果需要,它可以 return 不止一行。

-- Start and end dates should be the first day of the month
DECLARE @StartDate date = '20141201';
DECLARE @EndDate   date = '20150201';

SELECT
    CurrentMonth
    ,FIELD1
    ,FIELD2
    ,Counts
FROM
    Numbers
    CROSS APPLY
    (
        SELECT DATEADD(month, Numbers.Number-1, @StartDate) AS CurrentMonth
    ) AS CA_Month
    CROSS APPLY
    (
        SELECT
            FIELD1
            ,FIELD2
            ,COUNT(*) AS Counts
        FROM T
        WHERE
            OPENDATE < CurrentMonth
            AND (CLOSED >= CurrentMonth OR CLOSED IS NULL)
        GROUP BY
            FIELD1
            ,FIELD2
    ) AS CA
WHERE
    Numbers.Number < DATEDIFF(month, @StartDate, @EndDate) + 1
;

如果您提供 table 示例数据和预期输出,我可以验证查询是否产生正确的结果。

解决方案写在 SQL Server 2008 中。