计算在过去x个月中到目前为止尚未检查的项目数

时间:2015-05-15 17:39:03

标签: sql-server count

我们有一个项目列表。可以在最后的@FromDate到@ToDate(例如12个月)中对每个项目进行一次或多次检查/检查。我们如何计算自@FromDate以来从未检查过的一个月内检查过的项目数量,并每月显示该数量。

结果如下所示:

2014-05-01 00:00:00.000 1   May         2014    381
2014-06-01 00:00:00.000 2   June        2014    296
2014-07-01 00:00:00.000 3   July        2014    24
2014-08-01 00:00:00.000 4   August      2014    260
2014-09-01 00:00:00.000 5   September   2014    249
2014-10-01 00:00:00.000 6   October     2014    177
2014-11-01 00:00:00.000 7   November    2014    298
2014-12-01 00:00:00.000 8   December    2014    274
2015-01-01 00:00:00.000 9   January     2015    41
2015-02-01 00:00:00.000 10  February    2015    0
2015-03-01 00:00:00.000 11  March       2015    0
2015-04-01 00:00:00.000 12  April       2015    0

到目前为止,我们可以使用以下查询计算每月检查的项目数:

;WITH d AS 
(
    SELECT DATEADD(MONTH, n, DATEADD(MONTH, DATEDIFF(MONTH, 0, '2014-05-15'), 0)) as d, ROW_NUMBER() OVER (ORDER BY n) as rn
    FROM ( SELECT TOP (DATEDIFF(MONTH, '2014-05-15', '2015-04-15') + 1) 
    n = ROW_NUMBER() OVER (ORDER BY [object_id]) - 1
    FROM sys.all_objects ORDER BY [object_id] ) AS n
)    
SELECT 
    d.d,
    d.rn,
    DATENAME(MONTH, d.d) as [Month],
    YEAR(d.d) as [Year], 
    COUNT(DISTINCT ItemNumber) AS Count
FROM d LEFT OUTER JOIN ItemCheck
    ON CheckedTime >= d.d
    AND CheckedTime < DATEADD(MONTH, 1, d.d)
GROUP BY d.d, d.rn
ORDER BY d.d; 

但是,我们仍然无法弄清楚如何计算在2014年7月检查过但在2014年5月和6月从未检查过的物品数量。

下面的简单单个查询可以显示特定月份的查询,但不会按月显示。

select count(distinct ItemNumber) from ItemCheck
where CheckTime >= '2014-07-01' AND CheckTime < '2014-08-01' and
ItemNumber NOt in (SELECT ItemNumber FROM ItemCheck as t1 where t1.CheckTime >= '2014-05-01' AND t1.CheckTime < '2014-07-01')
order by ItemNumber

更新:ItemCheck表格如下所示:

CheckID | ItemNumber | CheckTime
1         i1           2014-05-02
2         i4           2014-06-12
3         i5           2014-07-03
4         i1           2014-08-01
5         i1           2014-08-02
6         i2           2014-09-15
7         i3           2014-10-11

1 个答案:

答案 0 :(得分:0)

假设您有一个名为months的表,其中一列名为month 那么你可以沿着这些方向做点什么:

DECLARE @date DATE
SET @date = '2014-01-01'

SELECT months.month AS currentMonth, COUNT(ItemNumber) ItemNumber from ItemCheck
CROSS JOIN months 
WHERE CheckTime >= dateadd(m, months.month - 1, @date) AND CheckTime < dateadd(m, months.month, @date) and
ItemNumber NOT IN (SELECT ItemNumber FROM ItemCheck AS t1 WHERE t1.CheckTime >= DATEADD(m, months.month - 3, @date) AND t1.CheckTime < dateadd(m, months.month - 1, @date))
GROUP BY month
ORDER BY ItemNumber

你也可以用一个函数来完成它,但你必须编写它(函数被称为dbo.Split,你可以这样写:select data from dbo.Split(',', '1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12')。这样你就可以避免创建另一个表(在记忆中或真实的..)

如果您想要dbo.Split的代码,我可以提供。