SQL将数据划分为行

时间:2015-02-24 18:31:27

标签: sql aggregate-functions

我有下表名为

表:活动

userid    appid    type
1         a        imp
2         a        imp
2         a        click
3         a        imp
4         a        imp
4         a        click
5         b        imp
5         b        click

我正在尝试计算每个appid的点击率。在这种情况下,我们将点击次数定义为(点击次数)/(展示次数)。我写了以下SQL:

SELECT appid, type, count(*) from activity group by appid, type

并得到以下结果:

输出:

appid    type       count(*)
a        click      2
a        imp        4
b        click      1
b        imp        1

下一步是进行划分。最后,我想实现以下目标:

目标:

appid    click-through
a        .5                        # 2/4 = .5
b        1                         # 1/1 = 1

这是如何实现的?理想情况下,我希望在一个查询中完成此操作,这可能吗?

4 个答案:

答案 0 :(得分:3)

您可以使用条件聚合来执行此操作:

   select appid
        , SUM(CASE WHEN type = 'click' THEN 1 END)*1.0
        / SUM(CASE WHEN type = 'imp' THEN 1 END) AS click_through
    from activity
    group by appid

演示:SQL Fiddle

如果使用MySQL,您可以进一步简化:

   select appid
        , SUM(type = 'click')*1.0
        / SUM(type = 'imp') AS click_through
    from activity
    group by appid

答案 1 :(得分:2)

只需计算子查询中的展示次数和点击次数,然后将它们连接在一起:

select appid, 
num_impressions, 
num_clicks, 
cast(num_clicks as float) / num_impressions as ctr
from(
    select appid, count(1) as num_impressions
    from activity
    where type = 'imp'
    group by appid
)a
join(
    select appid, count(1) as num_clicks
    from activity
    where type = 'click'
    group by appid
)b
on (a.appid = b.appid);

请注意num_clicksctr上的类型转换,以避免整数除法。

答案 2 :(得分:1)

您可以使用子查询执行此操作,因为您使用不同的条件处理两个不同的聚合:

SELECT d1.appid, (
   SELECT count(*) 
   FROM activity d2
   WHERE d2.appid = d1.appid
      d2.type = 'click'
) / (
   SELECT count(*)
   FROM activity d3
   WHERE d3.appid = d1.appid
      d3.type = 'imp'
) AS click_through
FROM activity d1;

答案 3 :(得分:0)

CREATE TABLE #activity
(
    userid  INT ,
    appid   VARCHAR(1),
    [type]  VARCHAR(5)
)

INSERT INTO #activity
VALUES
(1,         'a' ,       'imp'),
(2,         'a',        'imp'),
(2,         'a',        'click'),
(3,         'a',        'imp'),
(4,         'a',        'imp'),
(4,         'a',        'click'),
(5,         'b',        'imp'),
(5,         'b',        'click')


SELECT A.appid, CAST(a.Clicks AS FLOAT)/B.Imp
FROM 
(   SELECT appid, COUNT(1) Clicks
    FROM #activity
    WHERE [type] ='CLICK'
    GROUP BY appid
) A
INNER JOIN 
(   SELECT appid, COUNT(1) Imp
    FROM #activity
    WHERE [type] ='imp'
    GROUP BY appid
) B ON A.appid = B.appid

DROP TABLE #activity