SQL:每个过去一个月更新一行

时间:2015-02-25 17:03:30

标签: sql

我有一张存储缺陷的表格。 每个缺陷都有检测日期和结束日期。

我想提取截至当前日期的每个月的信息,关于该月份的未决缺陷数量。

例如,假设这些是我在数据库中的所有缺陷:

defect 1 - Detected in (01-01-2014)  , Closed in (04-03-2014)
defect 2 - Detected in (07-02-2014)  , Closed in (null) (still open)

我想提取信息如下:

01-01-2014 - 1 open defect  (defect 1 was created)
01-02-2014 - 2 open defects (defect 2 was created)
01-03-2014 - 1 open defect  (defect 1 was closed this month)
01-04-2014 - 1 open defect  (defect 2 was never closed so I would get entries up to today)
...
...
01-02-2015 - 1 open

有没有办法在不使用函数的情况下通过单个查询获取此信息?

2 个答案:

答案 0 :(得分:0)

避免问题"为什么没有功能",可以使用下面的查询返回N个月(限制适用)。只需更换" 16" in" WHERE n< 16"你想要评估的月数

; WITH Numbers (n) AS (
    SELECT  1
    UNION ALL
    SELECT  n + 1
    FROM    Numbers
    WHERE   n < 16
)
, NextMonth (dt) AS (
    SELECT  CAST( CAST( DATEPART(YEAR,GETDATE()) AS VARCHAR ) + '-' + CAST( DATEPART(MONTH,GETDATE())+1 AS VARCHAR ) + '-1' AS DATETIME )
)
, PriorMonths (dt) AS (
    SELECT  DATEADD( MONTH, -1 * n, dt )
    FROM    NextMonth
    CROSS JOIN Numbers
), RawData ( y, m, DateOpened ) AS (
    SELECT  DATEPART( YEAR, dt )
    ,       DATEPART( MONTH, dt )
    ,       t.DateOpened
    FROM    PriorMonths AS pm
    LEFT JOIN    @t AS t
        ON  DATEADD(MONTH,-1,t.DateOpened) < dt
        AND (DATEADD(MONTH,-1,t.DateClosed) >= dt OR t.DateClosed IS NULL)
)
SELECT  y, m, COUNT(DateOpened)
FROM    RawData
GROUP BY y, m
ORDER BY y DESC, m DESC

答案 1 :(得分:0)

首先,我想指出我已经使用了MS SQL Server T-SQL函数DATEADD()DATEDIFF()GETDATE() - 应该有任何类似的等价物您想要使用的SQL。

变量@startDate应设置为您要报告的范围的开头。

DECLARE @startDate DATE;
DECLARE @endDate DATE;
SET @startDate = '20140101';
SET @endDate = DATEADD(m, DATEDIFF(m, 0, GETDATE()), 0);

WITH Dates (dEnd, dStart) AS (
    SELECT DATEADD(M, 1, @endDate), @endDate
    UNION ALL
    SELECT  DATEADD(M, -1, dEnd), DATEADD(M, -1, dStart)
    FROM    Dates
    WHERE   dEnd > @startDate
)
SELECT dStart AS 'Month start', COUNT(Defects.reportedDate) AS 'Open defects'
FROM Dates
LEFT OUTER JOIN Defects ON 
    Defects.reportedDate < dEnd AND (Defects.resolvedDate IS NULL OR Defects.resolvedDate > dStart)
GROUP BY dStart
ORDER BY dStart;