SQL - 日期范围和输出数据中每月最后一天的搜索表?

时间:2016-01-07 14:32:50

标签: sql sql-server date stored-procedures

我有两张桌子:

Ticket_Report
Ticket_Report_Snapshot

Ticket_Report_Snapshot表是Ticket_Report表的精确副本,但有一个额外的列:

Snapshot_Date

每天拍摄Ticket报告表的快照,Snapshot_date是拍摄快照的日期。

我正在使用的两个表的列是:

Project_group, Ticket_Status

我需要创建一个带有2个Date参数的存储过程。从这两个日期开始,我需要在每个月的最后一天打印每个项目的所有打开的门票的计数,在两个日期之间(要在Ticket_report_snapshot的Snapshot_Date列中搜索每个月的最后一天)表)。

这是我到目前为止所做的:

--This query gives me the last day of any particular month
DECLARE @dtDate DATETIME
SET @dtDate = '1/6/2016'
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@dtDate)+1,0))
-- ouput: 2016-01-31 23:59:59.000


SELECT Project_Group as Project_Name,  count(ticket_status) as Open_Tickets 
FROM Ticket_Report_SnapShot
WHERE ticket_status != 'closed' AND ticket_status != 'cancelled'
AND snapshot_date = '2016-01-06'      
GROUP BY Project_Group

--Right now, the output is perfect for this 1 date, hard coded in
--OutPut:

Project_Name    Open_Tickets
Project 1       77
Project 2       5
Project 3       118
Project 4       22     --I need this kind of output, but for the last
Project 5       1      --day of each month between the 2 parameters
Project 6       2      --instead of just 1 date
Project 7       1

所以到目前为止我有2个查询,1个给我任何特定月份的最后一天,1个给我看一个特定硬编码日期的开放票。

如何编辑/组合这些查询以使用2个日期参数,并在2个日期范围之间为每个月的最后一天提供每个项目的开放票?

实施例。 2016年1月1日和2016年3月3日(1 / 31,2 / 29,3 / 31,将在ticket_report_snapshot表中的snapshot_date列中搜索这3个日期)

1 个答案:

答案 0 :(得分:3)

您可以使用递归cte获取日期并将快照表加入cte

DECLARE @StartDate DATETIME = '2016-01-01',
    @EndDate DATETIME = '2016-03-03';

WITH DateCTE AS 
(
    SELECT    EOMONTH(@StartDate) snapshot_date
    UNION ALL
    SELECT    EOMONTH(DATEADD(MONTH,1,snapshot_date))
    FROM      DateCTE
    WHERE     EOMONTH(DATEADD(MONTH,1,snapshot_date)) <= EOMONTH(@EndDate)
)
SELECT  Project_Group AS Project_Name,
        trs.snapshot_date,
        COUNT(ticket_status) AS Open_Tickets
FROM    Ticket_Report_SnapShot trs
        INNER JOIN DateCTE cte ON trs.snapshot_date = cte.snapshot_date
WHERE   ticket_status != 'closed'
        AND ticket_status != 'cancelled'
GROUP BY Project_Group,
        trs.snapshot_date 

如果您仍在使用SQL Server 2008,则可以使用此功能

DECLARE @StartDate DATETIME = '2016-01-01',
        @EndDate DATETIME = '2016-03-03';

WITH DateCTE AS 
(
    SELECT    DATEADD(dd,-1,DATEADD(mm,DATEDIFF(m,0,@StartDate) + 1,0)) snapshot_date
    UNION ALL
    SELECT    DATEADD(dd,-1,DATEADD(mm,DATEDIFF(m,0,DATEADD(MONTH,1,snapshot_date)) + 1,0))
    FROM      DateCTE
    WHERE     DATEADD(dd,-1,DATEADD(mm,DATEDIFF(m,0,DATEADD(MONTH,1,snapshot_date)) + 1,0)) <= DATEADD(dd,-1,DATEADD(mm,DATEDIFF(m,0,@EndDate) + 1,0))
)
SELECT  Project_Group AS Project_Name,
        trs.snapshot_date,
        COUNT(ticket_status) AS Open_Tickets
FROM    Ticket_Report_SnapShot trs
        INNER JOIN DateCTE cte ON trs.snapshot_date = cte.snapshot_date
WHERE   ticket_status != 'closed'
        AND ticket_status != 'cancelled'
GROUP BY Project_Group,
        trs.snapshot_date