按条件将多行数据转换为单行

时间:2016-09-07 22:01:17

标签: mysql sql sas

我的数据看起来像这样(添加的最后一列):

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

我希望在这些条件下每个id有一行数据:1。获取最早数据的条目。另外2.如果同一年有两个条目,请选择更高阶段的条目(var 1)Else 3.选择唯一的条目。您将如何简洁地编写一段SQL代码或SAS数据步骤?

3 个答案:

答案 0 :(得分:1)

这是优先级查询。这些都很棘手。这是一个使用变量枚举行的方法:

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 :(得分:0)

我相信聚合可以在这里使用而不使用任何变量,但我必须先做一个假设: - 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]

如果只有一个值将为该ID返回,因为它具有MIN Date值和Max Var1值。

答案 2 :(得分:0)

在SAS中,使用数据步骤非常简单。只需按所需顺序对数据进行排序,然后在数据步骤中使用first.id来提取第一个ID。我认为第一阶段'在你的帖子中是一个错字,应该说'第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;