如何每天获取行数(没有记录时填充空白)

时间:2016-03-22 15:06:32

标签: sql-server sql-server-2008

我有以下结果

Date       | EmployeeID 
2015-11-18 | 1          
2015-11-18 | 1          
2015-11-18 | 1          
2015-11-19 | 1          
2015-11-19 | 1          
2015-11-20 | 1          
2015-11-20 | 1          
2015-11-20 | 1          
2015-11-25 | 1          

但考虑到一系列日期(2015-11-15 - 2015-11-30),我想展示类似的东西

Date       | NbEmployees
2015-11-15 | 0
2015-11-16 | 0
2015-11-17 | 0
2015-11-18 | 3
2015-11-19 | 2
2015-11-20 | 3
2015-11-21 | 0
2015-11-22 | 0
2015-11-23 | 0
2015-11-24 | 0
2015-11-25 | 1
2015-11-26 | 0
2015-11-27 | 0
2015-11-28 | 0
2015-11-29 | 0
2015-11-30 | 0

我使用这种方法只能从表格中获取数据

DECLARE @StartDate DATE = '2015-11-15 00:00:00', @EndDate DATE = '2015-11-30 23:59:00'
DECLARE @CurrentDate DATE = @StartDate
DECLARE @DateRange TABLE (CurrentDate DATETIME)

WHILE(@CurrentDate <= @EndDate)
BEGIN
    INSERT INTO @DateRange VALUES(@CurrentDate)
    SET @CurrentDate = DATEADD(DAY, 1, @CurrentDate)
END

SELECT r.CurrentDate, COUNT(EmployeeID)
FROM Employee e
RIGHT JOIN @DateRange r ON e.HireDate = r.Date

结果:

Date       | NbEmployees
2015-11-18 | 3
2015-11-19 | 2
2015-11-20 | 3
2015-11-25 | 1

2 个答案:

答案 0 :(得分:1)

尝试这样

DECLARE @tbl TABLE([Date] DATE, EmployeeID INT);
INSERT INTO @tbl VALUES
 ('2015-11-18',1)          
,('2015-11-18',1)          
,('2015-11-18',1)         
,('2015-11-19',1)          
,('2015-11-19',1)          
,('2015-11-20',1)          
,('2015-11-20',1)          
,('2015-11-20',1)          
,('2015-11-25',1);

DECLARE @StartDate DATE = '2015-11-15 00:00:00', @EndDate DATE = '2015-11-30 23:59:00'
DECLARE @CurrentDate DATE = @StartDate
DECLARE @DateRange TABLE (CurrentDate DATETIME)

WHILE(@CurrentDate <= @EndDate)
BEGIN
    INSERT INTO @DateRange VALUES(@CurrentDate)
    SET @CurrentDate = DATEADD(DAY, 1, @CurrentDate)
END

SELECT CurrentDate,ISNULL(NbEmployees,0) AS NbEmployees
FROM @DateRange
LEFT JOIN
(
    SELECT COUNT(tbl.EmployeeID) AS NbEmployees
          ,tbl.[Date] AS Date
    FROM @tbl AS tbl    
    GROUP BY tbl.[Date]   
) AS grouped ON CurrentDate=grouped.[Date]  

结果

2015-11-15 00:00:00.000 0
2015-11-16 00:00:00.000 0
2015-11-17 00:00:00.000 0
2015-11-18 00:00:00.000 3
2015-11-19 00:00:00.000 2
2015-11-20 00:00:00.000 3
2015-11-21 00:00:00.000 0
2015-11-22 00:00:00.000 0
2015-11-23 00:00:00.000 0
2015-11-24 00:00:00.000 0
2015-11-25 00:00:00.000 1
2015-11-26 00:00:00.000 0
2015-11-27 00:00:00.000 0
2015-11-28 00:00:00.000 0
2015-11-29 00:00:00.000 0
2015-11-30 00:00:00.000 0

通过这样的方式,您可以即时创建日期记录(避免循环!!!

DECLARE @StartDate DATE = '2015-11-15 00:00:00', @EndDate DATE = '2015-11-30 23:59:00';
WITH DayCount(Nmbr) AS
(
    SELECT TOP (DATEDIFF(DAY,@StartDate,@EndDate)+1) ROW_NUMBER() OVER(ORDER BY (SELECT NULL))-1 FROM sys.objects
)
,RunningDates(CurrentDate) AS
(
    SELECT DATEADD(DAY,Nmbr,@StartDate) FROM DayCount
)
SELECT * FROM RunningDates

这绑定到sys.objects的最大数量...你会发现很多例子如何动态创建正在运行的数字或如何创建日期计数表(例如:{ {3}})

答案 1 :(得分:0)

您无需创建和维护list_of_dates表。你可以直接加入这样的事情:

对于SqlServer:

SELECT 
    DATEADD(DAY,number,'20010101') [Date]
FROM 
    master..spt_values
WHERE 
    type = 'P'
    AND DATEADD(DAY,number,'20010101') <= '20010104'

或者对于Oracle,这个:

select 
    rownum - 1 + to_date('01-JAN-2001', 'dd-mon-yyyy') dates
from 
    all_objects
where 
    rownum < to_date('01-FEB-2001', 'dd-mon-yyyy') - to_date('01-JAN-2001', 'dd-mon-yyyy') + 2

此查询的输出如下所示:

DATES    
---------
01-JAN-01
02-JAN-01
03-JAN-01
04-JAN-01
05-JAN-01
06-JAN-01
07-JAN-01
08-JAN-01
09-JAN-01
10-JAN-01
11-JAN-01
12-JAN-01
13-JAN-01
14-JAN-01
15-JAN-01
16-JAN-01
17-JAN-01
18-JAN-01
19-JAN-01
20-JAN-01
21-JAN-01
22-JAN-01
23-JAN-01
24-JAN-01
25-JAN-01
26-JAN-01
27-JAN-01
28-JAN-01
29-JAN-01
30-JAN-01
31-JAN-01
01-FEB-01