Подсчет количества последовательных вхождений для человека - SQL

У меня есть таблица, как:

Name | ID | Event
Smith| 1  | 
Smith| 2  | Y
Smith| 3  | 
Jones| 1  | 
Jones| 2  | Y
Jones| 3  | 
Jones| 4  | Y

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

Name | ID | Event | Event Count
Smith| 1  |       | 0
Smith| 2  | Y     | 1
Smith| 3  |       | 1
Jones| 1  |       | 0
Jones| 2  | Y     | 1
Jones| 3  |       | 1
Jones| 4  | Y     | 2

Я полагаю, я не могу сделать это в SQL? Если нет, можете ли вы быть очень ясно, как я поступаю с этим в SAS (или любым другим подходящим способом), так как я новичок в этом!

(К вашему сведению, это приводит к тому, что я могу различать строки, которые происходят до или после каждого события - т.е. фильтровать по событию = пусто, и все 0 происходило до первого события, любое 1 после и т. Д. Возможно, существует более простой способ сделай это.)

Спасибо!

3 ответа

Решение

Если вы хотите пойти по маршруту SAS, он считывает данные последовательно, поэтому очень хорошо справляется с такой проблемой.

data have;
infile datalines missover;
input Name $ ID  Event $;
datalines;
Smith 1   
Smith 2   Y
Smith 3   
Jones 1   
Jones 2   Y
Jones 3   
Jones 4   Y
;
run;

proc sort data=have;
by name id;
run;

data want;
set have;
by name id;
if first.name then event_count=0;
event_count+(event='Y');
run;

Вы можете сделать что-то подобное в запросе:

select Name, ID, Event,
    (
        select count(*)
        from MyTable
        where Name = t.Name
            and Event = 'Y'
            and ID <= t.ID
    ) as EventCount
from MyTable t

Коррелированный подзапрос найдет это количество для вас, хотя это что-то вроде треугольного соединения (ссылка на SQL Server, но все еще применимо), поэтому производительность не впечатляет.

Вот SQL Fiddle, показывающий результат.

Обратите внимание, что это должно работать практически в любой СУБД.

SELECT Name, ID, Event, grpTotal
FROM
  (
    select  Name,
            ID,
            Event,
            @sum := if(@grp = Name,@sum,0) + if(`Event` = 'Y',1,0) as grpTotal,
            @grp := Name
    from    TableName,
            (select @grp := '', @sum := 0) vars
    order   by  Name, ID
  ) s
Другие вопросы по тегам