在一列上区分,按计算列排序

时间:2017-02-10 22:15:47

标签: sql-server

这类似于this questionthis question,但我的情况略有不同,我无法让它发挥作用。

我正在使用SQL Server 2016.我现有的查询在下面,它工作正常。它会选择Interest行,并按照感兴趣的Post的数量对它们进行排序。

-- this is in a stored procedure, variables are valid

select i.[Id], i.[Name], i.[Description],
(
    select count(*) from [Post] p where p.[InterestId] = i.[Id] and p.[CreatedAt] >= @AfterTime
) as PostCount
from Interest i
order by PostCount desc
offset (@Start - 1) rows fetch next (@ReturnNum) rows only

我现在想改变这一点。兴趣表中还有另一列InterestCategoryId;这是与InterestCategory建立1:M关系的外键。我想获得与以前相同的信息,但仅限于一个InterestCategoryId - 我每个类别只能获得一个结果。我怎么能做到这一点?我正在尝试此代码,但它会引发PostCount不是有效列的错误。

select [Id], [Name], [Description], PostCount
from
(
    select [Id], [Name], [Description],
    (
        select count(*) from [Post] po where po.[InterestId] = [Id] and po.[CreatedAt] >= @AfterTime
    ) as PostCount,
    row_number() over(partition by [InterestCategoryId] order by PostCount desc) rn
    from [Interest]
) i
where rn = 1
order by PostCount desc
offset (@Start - 1) rows fetch next (@ReturnNum) rows only

示例兴趣数据如下。如果我们假设兴趣ID 1的帖子多于2,我会希望返回兴趣1,3和4。

ID | Name | Description | InterestCategoryId
---|------|-------------|-------------------
 1 | Test | Test int    | 1
 2 | Tes2 | Test int2   | 1
 3 | Tes3 | Test int3   | 2
 4 | Tes4 | Test int4   | 3

1 个答案:

答案 0 :(得分:0)

这不漂亮,但它运行。我希望它可以帮助你到达你想去的地方。

select [Id], [Name], [Description], PostCount
from
(
    select [Id], [Name], [Description],
    (
        select count(*) 
        from [Post] po 
        where po.[InterestId] = [Id] 
        and po.[CreatedAt] >= @AfterTime
    ) as PostCount,
    row_number() over(partition by [InterestCategoryId] order by (
        select count(*) 
        from [Post] po 
        where po.[InterestId] = [Id] 
        and po.[CreatedAt] >= @AfterTime
    ) desc) rn
    from [Interest]
) i
where rn = 1
order by PostCount desc
offset (@Start - 1) rows fetch next (@ReturnNum) rows only

如果您想避免重复COUNT子查询,请尝试这种方式。

select [Id], [Name], [Description], PostCount
from
(    
    select AA.Id, AA.Name, AA.Description, AA.PostCount, AA.[InterestCategoryId],
    row_number() over(partition by [InterestCategoryId] order by PostCount desc) rn
    from    (select [Id], [Name], [Description], [InterestCategoryId],
    (
        select count(*) 
        from [Post] po 
        where po.[InterestId] = [Id] 
        and po.[CreatedAt] >= @AfterTime
    ) as PostCount
    from [Interest]) AA
) i
where rn = 1
order by PostCount desc
offset (@Start - 1) rows fetch next (@ReturnNum) rows only

感谢您提醒OFFSET条款。我没有机会经常使用它。

希望这会有所帮助。祝你好运!