2017-05-12 49 views
1

我試圖得到出現在某個日期範圍內的用戶記錄數,特別是每個唯一用戶的最小(日期)和最小(日期)+ 14天。我已檢查此鏈接 SQL HAVING BETWEEN a date range 但它不是我要找的。這裏是我工作的一個例子,我所試圖做的最短日期範圍和其他日期之間的記錄計數

+----+------------+ 
| ID | ServiceDt | 
+----+------------+ 
| 10 | 2017-03-02 | 
| 10 | 2017-03-05 | 
| 10 | 2017-03-06 | 
| 10 | 2017-03-14 | 
| 10 | 2017-03-27 | 
| 11 | 2017-03-10 | 
| 11 | 2017-03-19 | 
| 11 | 2017-04-02 | 
| 11 | 2017-04-14 | 
| 11 | 2017-04-23 | 
| .. | ..   | 

查詢是:

SELECT ID, COUNT(ServiceDt) AS date_count 
FROM (
    SELECT ID, ServiceDt 
    FROM tbl 
    GROUP BY ID, ServiceDt 
    HAVING ServiceDt BETWEEN MIN(ServiceDt) AND DATEADD(day, +14, MIN(ServiceDt)) 
) AS R1 
GROUP BY ID 

當我做了上面的查詢,我得到以下結果。

+----+------------+ 
| ID | date_count | 
+----+------------+ 
| 10 | 5   | 
| 11 | 5   | 
| .. | ..   | 

我也試過使用CONVERT(date, ...),但是我得到的結果與上面相同。我想要的結果是

+----+------------+ 
| ID | date_count | 
+----+------------+ 
| 10 | 4   | 
| 11 | 2   | 
| .. | ..   | 

是否有人可以指導我我能做些什麼讓我的期望輸出,得益於

回答

1

使用窗口功能:

select id, count(*) 
from (select t.*, min(servicedt) over (partition by id) as min_sd 
     from tbl t 
    ) t 
where servicedt <= dateadd(day, 14, min_sd) 
group by id; 
+0

這正是我一直在尋找,謝謝 –

0

另一種選擇是使用cross apply()爲每個id獲得第一個ServiceDt,並在where子句中使用它。

select id, count(*) as date_count 
from t 
    cross apply (
    select top 1 
     i.ServiceDt 
    from t i 
    where i.Id = t.Id 
    order by i.ServiceDt 
    ) x 
where t.ServiceDt <= dateadd(day,14,x.ServiceDt) 
group by id 

rextester演示:http://rextester.com/WXA46698

回報:

+----+------------+ 
| id | date_count | 
+----+------------+ 
| 10 |   4 | 
| 11 |   2 | 
+----+------------+ 
相關問題