Using a SQL query, how can I select every date wit

2019-03-03 08:21发布

I'm querying a support ticket database, and each ticket has a column for "date opened" and "date closed." Tickets frequently remain open for multiple days, so we need to be able to pull the number of tickets that are OPEN on each day.
For example, for 4/8/14, we need to know how many tickets were opened on 4/8, combined with the total number of unclosed tickets that were opened prior to 4/8 but remained still open at 12:00am on 4/8 (may or may not have been closed during or after 4/8).

This seems straightforward enough for a single date, but now I need to write a query that will pull a complete range of dates.
For example, we need to write a query that returns every date between 1/1/14 and 4/10/14 along with the total number of tickets open on each date (including dates on which 0 tickets were open).

Is this possible using only queries or subqueries, without using any stored procedures or temporary datatables?
We're currently pulling the data into Excel and calculating the date stats there, but Excel is not a scalable solution and we'd like to have SQL perform this work so we can migrate this report to SSRS (SQL Server Reporting Services) down the road.

2条回答
我想做一个坏孩纸
2楼-- · 2019-03-03 09:09

You can't do it, without having some sort of date table that contains a row for each date possible. Creating a date table is pretty easy, depending on your RDBMS and your requirements.

查看更多
干净又极端
3楼-- · 2019-03-03 09:20

Your question is not very clear to me, but with SQLServer 2005 or better (SQLServer 2008 or better for the type Date) you can create a calendar. This one the way to do it

WITH [counter](N) AS
(SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
 SELECT 1)
, days(N) AS (SELECT row_number() over (ORDER BY (SELECT NULL)) FROM [counter])
, months (N) AS (SELECT N - 1 FROM days WHERE N < 13)
SELECT DISTINCT CAST(DATEADD(DAY, days.n, 
                             DATEADD(MONTH, months.n, '20131231')
                            ) AS date)
FROM months
     CROSS JOIN days
ORDER BY 1

if you need more year just add a new cte accordingly

SQLFiddle

查看更多
登录 后发表回答