У меня есть данные, которые выглядят так (последний добавленный столбец):

ID      Var 1       Date    What I Want
aa11     Stage I    1980    Delete
aa11     Stage 2    1980    Keep
aa22     Stage 1    1980    Keep
aa22     Stage 2    1990    Delete
aa33     Stage 3    1992    Keep

Но я хочу, чтобы это выглядело так:

ID  Var 1   Date
aa11    Stage 2 1980
aa22    Stage 1 1980
aa33    Stage 3 1992

Мне нужна одна строка данных для каждого идентификатора при следующих условиях: 1. Берутся записи с самыми ранними данными. В противном случае 2. Если в одном году есть две записи, выберите запись с более высокой стадией (var 1). Иначе 3. Возьмите дана единственная запись. Как бы вы вкратце написали фрагмент кода SQL или SAS Data-step?

0
DC2 8 Сен 2016 в 01:01

3 ответа

Лучший ответ

В SAS это очень просто с шагом данных. Просто отсортируйте данные в нужном порядке, а затем используйте first.id на шаге данных, чтобы извлечь первый идентификатор. Я предположил, что "Этап I" в вашем сообщении является опечаткой и должен сказать "Этап 1"

/* create original data */
data have;
infile datalines dsd;
input ID $ Var_1 $ Date; 
datalines;
aa11,Stage 1,1980
aa11,Stage 2,1980
aa22,Stage 1,1980
aa22,Stage 2,1990
aa33,Stage 3,1992
;
run;

/* sort dataset */
proc sort data=have;
by id date descending var_1;
run;

/* extract first id only */
data want;
set have;
by id;
if first.id;
run;
0
Longfish 8 Сен 2016 в 11:41

Я считаю, что здесь можно использовать агрегацию без использования каких-либо переменных, однако сначала я должен сделать одно предположение: - Данные Var 1 можно упорядочить последовательно, то есть: Этап 1 <Этап 2 <Этап 3 и т. Д.

Если это так, вы можете написать следующее, чтобы вернуть то, что вы ищете:

select
    ID
    --Aggregate results by Max Var1 value
    , max(Var1) as Var1
    , [Date]
from
    [YourTable] a
    --Derived Table to return ID and Var1 by lowest Date
    inner join
        (
            select
                ID
                , Var1
                , min([Date]) as [Date]
            from    
                [YourTable]
            group by
                ID
                , Var1
        ) b on a.ID = b.Id
group by
    Id
    , [Date]

В случае, если для этого идентификатора будет возвращено только одно значение, поскольку оно имеет как значение MIN Date, так и значение Max Var1.

0
Rob Hesje 7 Сен 2016 в 22:38

Это приоритетный запрос. Это сложно. Вот метод с использованием переменных для перечисления строк:

select t.*
from (select t.*,
             (@rn := if(@id = id, @rn + 1,
                        if(@id := id, 1, 1)
                       )
             ) as seqnum
      from t cross join
           (select @rn := 0, @id := '') params
      order by id, year asc, var1 asc
     ) t
where seqnum = 1;

Логика приоритезации обрабатывается предложением order by. Строки пронумерованы для каждого id на основе дополнительных ключей. Затем внешний запрос берет первую встреченную строку.

1
Gordon Linoff 7 Сен 2016 в 22:05