2013-05-23 3 views
3

у меня есть данные, как это:группы по диапазонам дат (Teradata)

Date    User ID 
2012-10-11   a 
2012-10-11   b 
2012-10-12   c 
2012-10-12   d 
2012-10-13   e 
2012-10-14   b 
2012-10-14   e 

То, что я хочу сделать, это группа самым последним диапазоном два дня (в моем реальном запросе, будет 7 дней) на каждый день и получить количество различных идентификаторов пользователей.

Например, я хочу, чтобы результат выглядеть следующим образом:

Date    count(distinct userIDs) 
2012-10-12   4 
2012-10-13   3 
2012-10-14   2 

Например, для 2012-10-12 я получить количество 4, потому что у меня есть «а», «б ', ' c ', и ' d '. "==> 'а' и 'б' приходят в предыдущий день, и 'C' и 'd' из того же день, 2012-10-12.

Аналогично, для 2012-10-13, я смотрю на 2012-10-13 и 2012-10-12, и я получаю 'с', 'd' и 'е'.

Тип данных столбца Дата - дата. Я использую Teradata.

Я пытался исследовать его, но не смог найти прямой ответ, который относится к моей ситуации. : -/Извините, если это повторение. Ваша помощь очень ценится. Спасибо!

+0

Я уверен, что есть способ чтобы сделать это, используя функции окна, что-то вроде 'SELECT date, COUNT (different user_id) OVER (PARTITION BY date ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)' (что неверно, я попробовал). Я буду играть с этим сам, пока не выясню это! – BellevueBob

ответ

2

Чтобы сделать то, что вы хотите, вам действительно нужно «размножить» данные, потому что каждая строка может быть включена в две даты для окончательной агрегации.

Я думаю, что самый простой подход для этого является union all подход:

select date, count(distinct userId) 
from ((select date, UserId 
     from t 
    ) union all 
     (select date + 1, UserId  -- combine with yesterday's data 
     from t 
    ) 
    ) t 
group by date; 

Потому что вы имеете дело с 7 дней, здесь альтернативный подход:

select (t.date + n), count(distinct t.UserId) 
from t cross join 
    (select 0 as n union all select 1 union all select 2 union all select 3 union all 
     select 4 union all select 5 union all select 6 
    ) n 
group by t.date + n; 
+0

Спасибо, Гордон, это на самом деле похоже на то, что я закончил (кроме того, я думаю, что было бы правильнее использовать «date + 1» в пятой строке, потому что, например, я хочу видеть вчерашних пользователей в сегодняшней группе) Я предоставлю свой подход в отдельном посте. –

+0

@ пользователь1621315. , , Я понимаю, что вы говорите. Я изменил знаки в ответе. –

2

Я не совсем знаком с синтаксисом Teradata, поэтому я буду использовать redbrick, чтобы показать вам логику.

select date, count(distinct userid) records 
from yourtable 
where date >= dateadd(day, -2, current_date) 
group by date 
order by date 

Edit начинается здесь

После дальнейшего рассмотрения, если заменить

where date >= dateadd(day, -2, current_date) 

с

where date >= current_date - 2 

, то вы должны быть хорошо идти.

+0

Благодарим вас за ответ.Я понимаю логику, но не приведет ли это только к одной строке (потому что она фильтрует даты в таблице столбцов current_date минус 2)? Мне нужно делать это каждый день, который доступен в таблице. –

+0

@ user1621315: Термин ** по дате ** вызывает teradata (или любой БД, так как он является «нормальным» SQL), чтобы подсчитывать разные (отдельные) идентификаторы пользователей каждый день. Идентификаторы пользователей сгруппированы по дате, затем подсчитываются. – lexu

+0

@ user1621315, возможно, вы могли бы уточнить термин «самый последний двухдневный диапазон». Вот что вдохновило фильтр на current_date -2. –

Смежные вопросы