我们有一个项目列表。可以在最后的@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
答案 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
的代码,我可以提供。