2016-06-06 2 views
0

Я хотел бы сделать подсчет числа, но считать последовательные даты как один экземпляр. В приведенной ниже таблице примеров 09/28/2013 и 09/29/2013 являются последовательными, поэтому они считаются одним экземпляром.Количество последовательных дат в SQL как один экземпляр

user_id  date 
------  ------ 
ABC123  09/28/2013 
ABC123  09/29/2013 
ABC123  09/30/2013 
ABC123  10/01/2013 

Выход:

user_id  date_count 
------  ------ 
ABC123  3 
+1

Это довольно просто. Посмотрите на эту статью, которая объясняет довольно четко. http://www.sqlservercentral.com/articles/T-SQL/71550/ –

+0

Это запрос запросов «пробелов и наклонностей». –

+0

Возможный дубликат [SQL Server GROUP BY COUNT Только последовательные строки] (http://stackoverflow.com/questions/29735846/sql-server-group-by-count-consecutive-rows-only) –

ответ

0

Это было взято из Sean Lange комментария. Его ссылка (HERE) была подходящей для вас. Окончательный код из ссылки был ...

WITH 
cteGroupedDates AS 
(--=== Find the unique dates and assign them to a group. 
-- The group looks like a date but the date means nothing except that adjacent 
-- dates will be a part of the same group. 
SELECT UniqueDate = SomeDate, 
    DateGroup = DATEADD(dd, - ROW_NUMBER() OVER (ORDER BY SomeDate), SomeDate) 
FROM #MyHead 
GROUP BY SomeDate 
) 
--===== Now, if we find the MIN and MAX date for each DateGroup, we'll have the 
-- Start and End dates of each group of contiguous daes. While we're at it, 
-- we can also figure out how many days are in each range of days. 
SELECT StartDate = MIN(UniqueDate), 
    EndDate = MAX(UniqueDate), 
    Days  = DATEDIFF(dd,MIN(UniqueDate),MAX(UniqueDate))+1 
FROM cteGroupedDates 
GROUP BY DateGroup 
ORDER BY StartDate 
; 

внесение некоторых изменений имен, чтобы попытаться сделать его легче понять ...

WITH 
dateGroup AS 
(--This is used to distinguish the different continuous sets of dates  
SELECT UniqueDate = date, 
    DateGroup = DATEADD(dd, - ROW_NUMBER() OVER (ORDER BY date), date) 
FROM userdate 
GROUP BY date 
) 

--Using dateGroup to get the groups of dates we can utilize it to get the count for them 
SELECT StartDate = MIN(UniqueDate), 
    EndDate = MAX(UniqueDate), 
    Days  = DATEDIFF(dd,MIN(UniqueDate),MAX(UniqueDate))+1, 
    u.user_id 
FROM dateGroup JOIN userdate u ON u.date = UniqueDate 
GROUP BY DateGroup, u.user_id 
ORDER BY StartDate 
; 

Я добавил JOIN userdate u ON u.date = UniqueDate после FROM dateCount получить Идентификатор пользователя. Также добавлен u.user_id в группу. Не работает, потому что u.user_id находится в SELECT (нужна информация в SELECT в GROUP BY).

данные из таблицы:

Data From Table

Доказательство:

Proof

---------- РЕДАКТИРОВАТЬ 1 ----- -----

Я собираюсь угадать, чего вы действительно хотите!

Это то, что я подошел. Два разных запроса с одинаковыми результатами.

Первый запрос:

WITH 
dateGroup AS 
(--This is used to distinguish the different continuous sets of dates  
SELECT UniqueDate = date, 
DateGroup = DATEADD(dd, - ROW_NUMBER() OVER (ORDER BY date), date), 
user_id 
FROM userdate 
GROUP BY date, user_id 
), 
userIDGroup AS 
(--This is used to get the previous table that you saw in my original answer 
SELECT COUNT(d.user_id) as 'Instances', 
d.user_id 
FROM dateGroup d 
GROUP BY DateGroup, d.user_id 
) 

SELECT 
COUNT(u.user_id) AS 'Instances', 
u.user_id 
FROM userIDGroup u 
GROUP BY u.user_id 
; 

Второй запрос (тот, который я предпочитаю):

WITH 
dateGroup AS 
(--This is used to distinguish the different continuous sets of dates  
SELECT UniqueDate = date, 
DateGroup = DATEADD(dd, - ROW_NUMBER() OVER (ORDER BY date), date), 
user_id 
FROM userdate 
GROUP BY date, user_id 
) 

SELECT count(c.user_id) AS 'Instances', c.user_id 
FROM 
(
SELECT COUNT(d.user_id) as 'Instances', 
d.user_id 
FROM dateGroup d 
GROUP BY DateGroup, d.user_id 
) c GROUP BY c.user_id 
; 

Доказательство:

enter image description here

+0

Не совсем то, что мне нужно. Все, что я хочу, это количество дат, но все последовательные блоки даты должны считаться 1 экземпляром. Мне не нужно количество дней в дате bock. Например, 1 января, 2 января, 3 января считаются 1. Извините, если я не объясню это четко. – Filip

+0

@Filip Нет, вы не объяснили это в вопросе. Я просто забыл об этом, когда посмотрел ссылку. В вашем вопросе не должно быть вашего вывода 1? Так как есть только один блок? Я немного смущен, это ваш выход. Вы хотите, чтобы общее количество «последовательных блоков даты»? – CodyMR

+0

Я хочу, чтобы общее количество «последовательных блоков даты» плюс любые другие даты, которые существуют для этого конкретного пользователя__и_ – Filip

0

Вызвать вашу исходную таблицу users_and_dates, ниже будет отбрасываться любая дата, когда следующий день также находится в наборе данных.

select t1.user_id, 
    count(*) 
from users_and_dates t1 
join users_and_dates t2 
    on t1.user_id=t2.user_id 
     and t1.date+1=t2.date 
where t2.user_id is null