从子表

时间:2016-10-16 20:03:26

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

三个相关表格:曲目(音乐曲目),用户和跟随。

下表是用户(关注者)与用户(关注者)之间的多对多关系。

我正在寻找这个作为最终结果: <track_id><user_id><most popular followee>

前两列很简单,是由曲目和用户之间的关系产生的。第三是我的问题。我可以使用下面的表加入所有的每个用户遵循的跟随者,但是如何跟随最多的跟随者。

以下是包含相关列的表格:

tracks: id, user_id (fk to users.id), song_title
users: id
follows: followee_id (fk to users.id), follower_id (fk to users.id)

以下是一些示例数据:

TRACKS
1, 1, Some song title

USERS
1
2
3
4

FOLLOWS
2, 1
3, 1
4, 1 
3, 4
4, 2
4, 3

DESIRED RESULT
1, 1, 4

对于所需的结果,第3个字段为4,因为您可以在FOLLOWS表中看到,用户4拥有最多的关注者。

我和我周围的一些伟大思想仍然在摸不着头脑。

2 个答案:

答案 0 :(得分:1)

所以我把它扔进了Linqpad,因为我对Linq更好。

Tracks
    .Where(t => t.TrackId == 1)
    .Select(t => new { 
        TrackId = t.TrackId,
        UserId = t.UserId, 
        MostPopularFolloweeId = Followers
            .GroupBy(f => f.FolloweeId)
            .OrderByDescending(g => g.Count())
            .FirstOrDefault()
            .Key
    });

生成的SQL查询如下(@ p0是轨道ID):

-- Region Parameters
DECLARE @p0 Int = 1
-- EndRegion
SELECT [t0].[TrackId], [t0].[UserId], (
    SELECT [t3].[FolloweeId]
    FROM (
        SELECT TOP (1) [t2].[FolloweeId]
        FROM (
            SELECT COUNT(*) AS [value], [t1].[FolloweeId]
            FROM [Followers] AS [t1]
            GROUP BY [t1].[FolloweeId]
            ) AS [t2]
        ORDER BY [t2].[value] DESC
        ) AS [t3]
    ) AS [MostPopularFolloweeId]
FROM [Tracks] AS [t0]
WHERE [t0].[TrackId] = @p0

输出预期的响应,应该是更清晰的查询的开始。

答案 1 :(得分:0)

这听起来像是row_number()的聚合查询。关于所有连接如何结合起来我有点困惑:

select t.*
from (select t.id, f.followee_id, count(*) as cnt,
             row_number() over (partition by t.id order by count(*) desc) as seqnum
      from followers f join
           tracks t 
           on f.follow_id = t.user_id
      group by t.id, f.followee_id
     ) t
where seqnum = 1;