Mysql 计算用户通过sql看到的唯一项
我需要帮助来解决下一个案子 用户希望查看的数据可通过分页请求访问,稍后这些请求将以下一种形式存储在数据库中:Mysql 计算用户通过sql看到的唯一项,mysql,sql,Mysql,Sql,我需要帮助来解决下一个案子 用户希望查看的数据可通过分页请求访问,稍后这些请求将以下一种形式存储在数据库中: +----+---------+-------+--------+ | id | user id | first | amount | +----+---------+-------+--------+ | 1 | 1 | 0 | 5 | | 2 | 1 | 10 | 10 | | 3 | 1 | 10 |
+----+---------+-------+--------+
| id | user id | first | amount |
+----+---------+-------+--------+
| 1 | 1 | 0 | 5 |
| 2 | 1 | 10 | 10 |
| 3 | 1 | 10 | 5 |
| 4 | 1 | 15 | 10 |
| 5 | 2 | 0 | 10 |
| 6 | 2 | 0 | 5 |
| 7 | 2 | 10 | 5 |
+----+---------+-------+--------+
该表按用户id asc、第一个asc、金额描述排序
任务是编写SQL语句,计算用户看到的唯一数据总量
对于第一个用户,总金额必须为20,因为id=1的请求返回了前5项,id=2的请求返回了另外10项。id=3的请求返回id=2的请求已经“看到”的数据。id=4的请求与id=2的请求相交,但仍返回5条“未看到”的数据
对于第二个用户,总金额必须为15
作为SQL语句的结果,我应该得到下一个输出:
+---------+-------+
| user id | total |
+---------+-------+
| 1 | 20 |
+---------+-------+
| 2 | 15 |
+---------+-------+
我使用的是MySQL 5.7,所以窗口函数对我来说不可用。我已经做了一天的这项工作,但仍然无法达到预期的效果。如果此设置不可行,我将在应用程序代码中计算结果。我将感谢任何建议或帮助解决这项任务,谢谢 这是一种缺口和孤岛问题。在这种情况下,使用累计最大值确定一个请求是否与前一个请求相交。如果不是,那就是相邻请求孤岛的开始。初始值的累积和分配一个岛,然后聚合计算每个岛 所以,这些岛屿看起来像这样:
select userid, min(first), max(first + amount) as last
from (select t.*,
sum(case when prev_last >= first then 0 else 1 end) over
(partition by userid order by first) as grp
from (select t.*,
max(first + amount) over (partition by userid order by first range between unbounded preceding and 1 preceding) as prev_last
from t
) t
) t
group by userid, grp;
然后,您希望通过userid对其进行汇总,这是一个更高级别的聚合:
with islands as (
select userid, min(first) as first, max(first + amount) as last
from (select t.*,
sum(case when prev_last >= first then 0 else 1 end) over
(partition by userid order by first) as grp
from (select t.*,
max(first + amount) over (partition by userid order by first range between unbounded preceding and 1 preceding) as prev_last
from t
) t
) t
group by userid, grp
)
select userid, sum(last - first) as total
from islands
group by userid;
是一个dbfiddle。此逻辑与Gordon的类似,但也运行在MySQL的旧版本上
select userid
-- overall length minus gaps
,max(maxlast)-min(minfirst) + sum(gaplen) as total
from
(
select userid
,prevlast
,min(first) as minfirst -- first of group
,max(last) as maxlast -- last of group
-- if there was a gap, calculate length of gap
,min(case when prevlast < first then prevlast - first else 0 end) as gaplen
from
(
select t.*
,first + amount as last -- last value in range
,( -- maximum end of all previous rows
select max(first + amount)
from t as t2
where t2.userid = t.userid
and t2.first < t.first
) as prevlast
from t
) as dt
group by userid, prevlast
) as dt
group by userid
order by userid
>请参阅谢谢您的详细解释,我会考虑更新环境来使用MySQL 8.谢谢,这就是MySQL 5.7所需要的。