2016-03-22 5 views
1

Ben şu sonuçlargünde satırları

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   

Ama tarih bir dizi (2015/11/15 - 2015/11/30) verdik (hiçbir kayıt sırasında boşlukları doldurun) almak için nasıl istiyorum sadece verilerle tablodan değerleri almak tarafından bu yaklaşımı kullanarak ettik bu

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 

gibi görüntülü şey

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 

Sonuçlar:

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

Genellikle en basit yol, bir takvim tablosu (= günde 1 satır) oluşturmak ve sorgunuzla buna katılmaktır. –

+0

Ben de öyle yaptım. Örnek koduma bak. Takvimim @DateRange –

+0

Hangi SQL Server sürümü? – Shnugo

cevap

1

size anında Tarih-çetelesini yaratabilecek bu

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] 

gibi bir sonuç

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 

böyle bir şey ile deneyin (önlemek döngüler !!!)

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 

Bu sys.objects max sayısı bağlıdır ... Sen anında çalışan sayıları oluşturmak veya nasıl örneğin bunun için (tarih-taksitli tablo oluşturmak için nasıl örnekler çok bulacaksınız : https://stackoverflow.com/a/32474751/5089204)

+0

Bu döngü yerine bir numara/sayılar tablosu ile daha iyi olurdu. –

+0

@SeanLange, Biliyorum :-) Ben sadece orijinal kodu alıp değiştirdim. Şu anda bunu anında yaratmak için küçük bir örnek yazıyorum ... – Shnugo

0

Liste_of_dates tablosu oluşturmanıza ve korumanıza gerek yoktur. Sadece outter böyle bir şey için katılabilecek:

SqlServer için:

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

Veya Oracle için

bu:

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 

bu sorgu çıktısı şuna benzer:

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