复杂的SQL聚合

时间:2012-06-05 14:37:54

标签: tsql aggregation

我有一个类似的数据集:

X | U | datetime
-------------
1 | 1 | 1/1/12
1 | 2 | 1/1/12
1 | 2 | 1/1/12
1 | 2 | 1/1/12
1 | 4 | 1/1/12
2 | 2 | 2/1/12
2 | 3 | 2/1/12
1 | 3 | 3/1/12
2 | 4 | 3/1/12
3 | 2 | 4/1/12

这是一次访问记录。 X是所访问事物的ID,U是用户ID

我需要计算两个统计数据。

给定X(x)的值:

1)“新访问者”:计算首次访问任意X的唯一身份用户数x

用例:

  • 用户仅访问了x一次 - >算作1
  • 用户仅访问了!x一次 - >计为0
  • 用户仅访问了x两次 - >算作1
  • 用户仅访问了!x两次 - >计为0
  • 用户访问了许多X,其中任何X的首次访问是x - >算作1
  • 用户访问了许多X,其中任何X的首次访问是!x - >计为0

以上数据的例子:

X | Count
---------
1 | 3
2 | 1
3 | 0

2)“返回访问者”:计算曾多次访问x或曾访问x一次的唯一身份用户数,但之前曾访问过另一个X(即访问过后的访问次数)访问x不计算在内)

以上数据的例子:

X | Count
---------
1 | 3
2 | 2
3 | 1 

我正在使用SQL Server 2008,任何帮助都非常感谢。谢谢!

更新

这似乎回答Q1,虽然我不是很快:(

select x.X, COUNT(1)
from (
    select t1.X
    from @t t1
    group by t1.X, t1.U
    having (select COUNT (1) from @t t2 where t2.u= t1.U and t2.OccurredOn < MIN(t1.OccurredOn)) =0 
) x 
group by x.X

更新2

认为这是(2)

select t.X, COUNT(1)
from @t t
left join (
    select t.U, MIN(t.OccurredOn) as O
    from @t t
    group by t.U
) x on t.U = x.U and t.OccurredOn <= x.O
where x.U is null
group by t.X

1 个答案:

答案 0 :(得分:1)

对于第一种情况,您需要一个要加入的子查询,这将过滤掉所有不属于同类的用户访问。所以你会有像

这样的东西
select X, count(*) [First Visits]
from table t1
     join (select U, min(datetime) firstvisit 
           from table 
           group by U) t2 on t1.datetime = t2.firstvisit and t1.U = t2.U
group by X

编辑:我认为您对第二个问题的解决方案很好,但如果您使用<=替换=,则加入会更快。