每组中最高的值出现

时间:2011-01-21 19:02:42

标签: sql mysql greatest-n-per-group

我的桌子上有一个用户ID和他浏览过的Webside-ID。该表如下所示:

| user-ID | website-ID |
|       1 |          1 |
|       1 |          2 |
|       1 |          1 |
|       1 |          4 |
|       2 |          1 |
|       2 |          2 |
|       2 |          5 |
|       2 |          2 |

我想选择每个用户最常用的网站ID。正如您所看到的, min max avg 在这里不起作用。有任何想法吗?

4 个答案:

答案 0 :(得分:3)

我引入了一个临时表,只是为了让事情更容易阅读。您当然可以替换内联查询,并在需要时删除临时表。

第一个选项汇总了每个用户和网站的访问次数。

第二个选择查找子查询中每个用户的最大访问次数,然后连接回临时表以查找其计数与该最大值匹配的网站。

create temporary table TempSum
    select user-ID, website-ID, count(*) as TotalCount
        from YourTable
        group by user-ID, website-ID

select ts.user-ID, ts.website-ID, ts.TotalCount
    from (select user-ID, max(TotalCount) as MaxCount
              from TempSum
              group by user-ID) ms
        inner join TempSum ts
            on ts.user-ID = ms.user-ID
                and ts.TotalCount = ms.MaxCount

答案 1 :(得分:0)

我不确定我的问题是对的。如果您想获得访问次数最多的网站ID,可以使用:

select count(user-ID) as cnt from dataTable group by website-ID order by cnt desc

答案 2 :(得分:0)

这可能看起来很复杂,但它只汇总数据一次,然后通过它对结果进行排名并仅选择第一个

select userid, websiteid, visits
from
(
select 
 userid, websiteid, visits,
 @r := case when @u=userid then @r+1 else 1 end r,
 @u := userid
from
(select @u:=null) x,
(select userid, websiteid, count(*) visits
 from visit
 group by userid, websiteid
 order by userid, visits desc) y
) z
where r=1

内部选择为每个用户 - 网站组合生成计数,并按最多访问次数进行排序。然后将其传递给对记录per user进行排名的中间查询,并在列r中给出排名。

这是一个变体,它将显示具有EQUAL等级的用户的所有网站。与上一个查询的不同之处在于,如果网站A和B都有10次来自用户X的访问,则A和B都会在结果中列出,而之前的查询会随机选择一个来显示。

select userid, websiteid, visits
from
(
select 
 userid, websiteid, visits,
 @r := case
    when @u=userid and @v=visits then @r  # same rank
    when @u=userid then @r+1              # next rank
    else 1                                # different user
    end r,
 @u := userid, @v := visits
from
(select @u:=null, @v:=null) x,
(select userid, websiteid, count(*) visits
 from visit
 group by userid, websiteid
 order by userid, visits desc) y
) z
where r=1

这是使用的测试表

create table visit (userid int, websiteid int);
insert into visit select 1,1;
insert into visit select 1,2;
insert into visit select 1,1;
insert into visit select 1,4;
insert into visit select 2,1;
insert into visit select 2,2;
insert into visit select 2,5;
insert into visit select 2,2;

答案 3 :(得分:0)

一步一步地完成,分餐。

请注意,显示的数据没有主键;有重复的行。据推测,完整数据集具有其他信息,例如访问时间,使行唯一。对于手头的问题并不重要,但是你的目标是尽可能地使用主键表(基本上总是如此)。

另请注意,标识符'user-ID'和'website-ID'在标准SQL中无效,除非将其视为分隔标识符;为了达到目的,破折号变为下划线。

此处理使用基本SQL。它不使用ROLAP扩展,也不使用为通用表达式命名的WITH子句。

每个用户访问每个网站的次数是多少次?

SELECT User_ID, Website_ID, COUNT(*) AS NumberOfVisits
  FROM WebSitesVisited
 GROUP BY User_ID, Website_ID;

用户访问任何网站的最大次数是多少?

SELECT User_ID, MAX(NumberOfVisits) AS MaxNumberOfVisits
  FROM (SELECT User_ID, Website_ID, COUNT(*) AS NumberOfVisits
          FROM WebSitesVisited
         GROUP BY User_ID, Website_ID
       ) AS V
 GROUP BY User_ID;

给定用户访问的网站次数最多?

SELECT V.User_ID, V.Website_ID, V.NumberOfVisits
  FROM (SELECT User_ID, MAX(NumberOfVisits) AS MaxNumberOfVisits
          FROM (SELECT User_ID, Website_ID, COUNT(*) AS NumberOfVisits
                  FROM WebSitesVisited
                 GROUP BY User_ID, Website_ID
               ) AS V2
         GROUP BY User_ID
       ) AS M
  JOIN (SELECT User_ID, Website_ID, COUNT(*) AS NumberOfVisits
          FROM WebSitesVisited
         GROUP BY User_ID, Website_ID
       ) AS V
    ON M.User_ID = V.User_ID AND M.NumberOfVisits = V.MaxNumberOfVisits
 ORDER BY V.User_ID;

请注意,如果用户X访问了站点Y和站点Z的次数相同(并且该用户X访问任何站点的次数最多),则Y和Z都将出现在用户X的列表中。