有一位播放器会播放视频。用户可以开始或停止视频。
每次用户播放视频时,都会显示video_click_id。我想在结束视频的系列停止中找到第一站的id。如果video_click_id以一站结束,则获取最后一站。如果video_click_id以两次停止结束,则获得第二个最后一站。如果video_click_id以3站结束,则获得第3站。
id video_click_id action_timestamp action
----------- ------------- ----------------------- ------
3 1 2016-05-19 13:59:07.437 play
4 1 2016-05-19 13:59:13.413 stop
6 1 2016-05-19 15:59:40.213 stop
8 2 2016-05-19 16:29:11.950 play
9 2 2016-05-19 16:29:27.090 stop
10 2 2016-05-19 16:29:28.000 play
12 2 2016-05-19 16:29:29.390 stop
13 3 2016-05-19 20:59:07.437 play
14 3 2016-05-19 20:59:13.413 stop
15 3 2016-05-19 20:59:40.213 stop
26 3 2016-05-19 20:59:40.213 stop
任何人都可以帮助我吗?我正在使用mssql。
提前致谢!
答案 0 :(得分:0)
在下面的查询中,子查询为每个stop
记录分配一个行号。然后,外部查询保留每个video_click_id
组的第一个停止记录。
SELECT
t.id,
t.video_click_id,
t.action_timestamp,
t.action
FROM
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY video_click_id ORDER BY action_timestamp) rn
FROM yourTable
WHERE action = 'stop'
) t
WHERE t.rn = 1
<强>输出:强>
在这里演示:
答案 1 :(得分:0)
您可以使用not exists
来检索不后跟播放的所有停靠点。然后,您可以使用group by
选择不后跟播放的最早id
停止:
select min(id), video_click_id
from mytable t1
where action = 'stop'
and not exists ( -- subquery ensures that no 'play' occurs after 'stop'
select 1 from mytable t2
where t2.video_click_id = t1.video_click_id
and t2.action = 'play'
and t2.id > t1.id
) group by video_click_id
答案 2 :(得分:0)
假设 id 是增量式的,您可以使用以下简单查询来获得所需的输出 -
SELECT MAX(id) AS id, video_click_id
FROM
(
SELECT *
, LAG(action) OVER(PARTITION BY video_click_id ORDER BY action_timestamp) AS prev_action
FROM MyTable
) AS p
WHERE action = 'stop' AND prev_action = 'play'
GROUP BY video_click_id;
子查询为每个操作找到上一个操作。我们希望在最后一次“播放”操作后立即执行“停止”操作。因此,选择id的最大值将获得视频实际停止的ID。
答案 3 :(得分:0)
嗯,蒂姆的答案对于问题的第一个版本是正确的,但是在编辑问题之后,它需要一个小的调整 - 在派生表中添加一个不存在的诀窍:
SELECT
t.id,
t.video_click_id,
t.action_timestamp,
t.action
FROM
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY video_click_id ORDER BY action_timestamp) rn
FROM yourTable t0
WHERE action = 'stop'
AND NOT EXISTS
(
SELECT 1
FROM yourTable t1
WHERE t1.video_click_id = t0.video_click_id
AND t1.action = 'play'
AND t1.action_timestamp > t0.action_timestamp
)
) t
WHERE t.rn = 1;
输出:
id video_click_id action_timestamp action
4 1 2016-05-19 13:59:13.413 stop
12 2 2016-05-19 16:29:29.390 stop
14 3 2016-05-19 20:59:13.413 stop