mysql计数总和if

vngu2lb8  于 2021-06-25  发布在  Mysql
关注(0)|答案(2)|浏览(276)

我有一个表,其中包含所有用户的每次登录。我想运行一个查询,该查询将提取每个用户登录的次数,但如果用户一天登录超过4次,则将其限制为4次。然后求和以获得总登录次数。此外,我想拉回来的总登录次数的时间框架。因此,我将总登录数指定为100,然后查询必须返回最早的日期,从今天开始计算每个用户的登录数(如果超过4,则限制为4)。
到目前为止,我的查询是获取每个用户限制为4个的总计列表:

SELECT (case when (count(l.user_id) > 4) then 4 else count(l.user_id) end) as cappedcount 
FROM `logins` l 
where l.store_id = 908 
and l.login_dt > '2018-04-17 00:00:00' and l.login_dt < '2018-04-18 23:59:59' 
group by l.user_id order by cappedcount desc

我现在正在指定日期范围,但不想在最终查询中这样做。

iq3niunx

iq3niunx1#

如果我理解正确,您只想查看每个用户和日期的最后四次登录,而忽略他们以前的登录。从这个集合中,您需要最后100次登录。
因此,第一个任务是获得每个用户和每一天的最后四次登录,这通常可以通过窗口函数来解决,但是mysql没有提供这些功能。因此,请改为在子查询中计数(这可能需要很长时间):

select *
from logins
where
(
  select count(*)
  from logins later
  where later.user_id = logins.user_id
    and date(later.login_dt) = date(logins.login_dt)
    and later.login_dt > logins.login_dt
) < 4
order by login_dt desc
limit 100;

我建议为此查询提供以下索引:

create index idx_logins on logins (user_id, login_dt);
b09cbbtk

b09cbbtk2#

您使用的mysql版本是什么?因为据我所知 with clause 仅在mysql的最新版本中受支持。
我相信你第一个要求的答案是:

select sum(cntx) from (
  select user_id, date(login_time), least(count(*), 4) cntx
    from logins
   where login_time between '2018-04-10 00:00:00' and '2018-04-17 00:00:00'
   group by user_id, date(login_time)
) x

您可以在sqlfiddle.com中查看。
对于你的第二个问题,我有下面的答案,我相信这不是最好的解决方案,但它在MySQL5.6上工作。在下一个mysql版本(MySQL8)中,您可以使用with子句,它为这个问题提供了更好的解决方案。我在解决方案中使用视图跳过重复查询:

create view xlogins as
select user_id, date(login_time) xdt, least(count(*), 4) xcnt
 from logins
group by user_id, date(login_time);

create view xxlogins as
select distinct xdt, (select sum(x2.xcnt)
                        from xlogins x2
                       where x2.xdt >= x1.xdt) sumx
  from xlogins x1;

select min(x1.xdt)
  from xxlogins x1
  join xxlogins x2 on x1.xdt < x2.xd
 where x1.sumx >= 100
   and x2.sumx <= 100

在这个sqlfiddle.com中找到解决方案,我刚刚将100改为10。

相关问题