【问题标题】:Counting number of sequential occurences for a person - SQL计算一个人的连续出现次数 - SQL
【发布时间】:2013-03-04 09:19:23
【问题描述】:

我有一张这样的桌子:

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,等等。可能有一个更简单的方法。)

谢谢!

【问题讨论】:

    标签: mysql sql sas cumulative-sum


    【解决方案1】:

    您可能会在查询中执行类似的操作:

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

    相关的子查询会为你找到这个计数,虽然这有点像 triangular join(SQL Server 链接,但仍然适用),所以性能不是很好。

    这是显示结果的SQL Fiddle

    请注意,这几乎适用于任何 RDBMS。

    【讨论】:

    • 太好了 - 谢谢。我不是 100% 确定它是如何工作的,但我会一直玩到我理解为止! SQL Fiddle 很棒!
    【解决方案2】:
    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
    

    【讨论】:

    • 谢谢。在性能方面,你的和蒂姆的哪个更好?
    • @user2174526 您应该在真实数据上测试这两个查询,看看哪个更快。
    【解决方案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;
    

    【讨论】:

    • 如果您使用的是 SAS,这绝对是正确的选择。应该比 SQL 快得多,因为如果数据已经排序,它只会遍历一次。
    • 太棒了 - 非常感谢。快速提问 - 如果数据已经排序,为什么还要对数据(第二个代码块)进行排序?如果没有我包含该代码,SAS 将无法运行它,但输入数据已经排序。为什么是'按名称ID;'第三位代码中需要吗?
    • 好吧,数据样本没有按字母顺序排序,所以我进入了这一步。如果您确定名称被组合在一起并且 id 被正确排序,则有一种方法可以避免排序。在这种情况下,将 NOTSORTED 选项添加到数据步骤中的 BY 语句中,这将在每次名称更改时重置计数器。 BY 语句是必需的,因为它可以访问 FIRST.var 自动变量。从技术上讲,您只需要其中的 NAME 变量,我添加了 ID 作为双重检查数据是否正确排序。所以该行可以说:按名称未排序;
    • 感谢您的解释 - 我很感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多