当行数超过特定计数时对行进行分组

Niy*_*tel 3 mysql

询问:

select city.name as name, sum(count) as views from profpostview
inner join professional as prof on prof.pfid = profpostview.viewerpfid
left join cityinfo as city on city.cityid = prof.cityid
where pfpid = _pfpid group by name order by views desc;
Run Code Online (Sandbox Code Playgroud)

输出:

**name , views**

'Ahmedabad', '14'
'Gandhinagar', '7'
'Mumbai', '5'
'Aalborg', '5'
'Rajkot', '3'
'Bhavnagar', '2'
'Baroda', '1'
Run Code Online (Sandbox Code Playgroud)

必需的:

**name, views**

'Ahmedabad', '14'
'Gandhinagar', '7'
'Aalborg', '5'
'others', '11
Run Code Online (Sandbox Code Playgroud)

解释:当行数超过 3 时,我想通过添加视图数来合并行。 Profpostview 表通过 pfpid 与 profpostinfo 相关联,而 profpostinfo 表又通过 cityid 与 cityinfo 相关联。

最终查询不应返回超过 4 行。第 3 行之后的所有(总和)行应分组为第 4 行。

ype*_*eᵀᴹ 5

如果 MySQL 已经实现了窗口函数或 CTE,这将是相当简单的(他们正在研究它,但尚未宣布它将出现在哪个版本中。)使用 CTE:

with grp as
  ( select city.name, sum(count) as views 
    from profpostview as ppview
      inner join professional as prof 
        on prof.pfid = ppview.viewerpfid
      left join cityinfo as city 
        on city.cityid = prof.cityid
    where pfpid = _pfpid 
    group by city.name
  ),
the_first_three as
  ( select name, views
    from grp
    order by views desc
    limit 3
   ),
the_rest as
  ( select name, views
    from grp
    order by views desc
    limit 900000000000000 offset 3
   )
select name, views
from the_first_three

union all 

select 'other', sum(views)
from the_rest 

order by (name = 'other'), views desc ;
Run Code Online (Sandbox Code Playgroud)

使用 CTE 和窗口函数:

with grp as
  ( select city.name, sum(count) as views,
           row_number() over (order by sum(count) desc) as rn 
    from profpostview as ppview
      inner join professional as prof 
        on prof.pfid = ppview.viewerpfid
      left join cityinfo as city 
        on city.cityid = prof.cityid
    where pfpid = _pfpid 
    group by city.name
  )
select name, views, rn
from grp
where rn <= 3

union all 

select 'other', sum(views), 4
from grp
where rn > 3 

order by rn ;
Run Code Online (Sandbox Code Playgroud)

在等待 CTE 和窗口函数实现的同时,在当前的 MySQL 版本中,我们将不得不重复代码或使用一些技巧来避免重复。无论如何,我认为我们无法避免进行两次分组和求和。这是获得所需输出的一种方法。它本质上是对上述代码 1 的重写,使用派生表而不是 CTE:

  ( select city.name, sum(count) as views 
    from profpostview as ppview
      inner join professional as prof 
        on prof.pfid = ppview.viewerpfid
      left join cityinfo as city 
        on city.cityid = prof.cityid
    where pfpid = _pfpid 
    group by city.name
    order by views desc
    limit 3
  )
union all   
  ( select 'other', sum(views)
    from 
      ( select city.name, sum(count) as views 
        from profpostview as ppview
          inner join professional as prof 
            on prof.pfid = ppview.viewerpfid
          left join cityinfo as city 
            on city.cityid = prof.cityid
        where pfpid = _pfpid 
        group by city.name
        order by views desc
        limit 900000000000000 offset 3
      ) grp
  )  
order by (name = 'other'), views desc ;
Run Code Online (Sandbox Code Playgroud)

如果您想以某种方式解决关系,请相应地更改order by,例如。到order by views desc, name asc