SQL 按行划分数据
SQL divide data in rows
我有以下 table 名为
Table: activity
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
这是如何实现的?理想情况下,我希望这在一个查询中完成,这可能吗?
只需计算子查询中的展示次数和点击次数并将它们合并在一起:
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);
注意 ctr
中 num_clicks
的类型转换以避免整数除法。
您可以使用子查询执行此操作,因为您正在使用不同的条件处理两个不同的聚合:
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;
您可以使用条件聚合来执行此操作:
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
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
我有以下 table 名为
Table: activity
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
这是如何实现的?理想情况下,我希望这在一个查询中完成,这可能吗?
只需计算子查询中的展示次数和点击次数并将它们合并在一起:
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);
注意 ctr
中 num_clicks
的类型转换以避免整数除法。
您可以使用子查询执行此操作,因为您正在使用不同的条件处理两个不同的聚合:
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;
您可以使用条件聚合来执行此操作:
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
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