首页 > 解决方案 > 根据计数对记录集进行分类

问题描述

我有学生在另一所学校没有被录取或被录取,但在一个或多个或我们的一个或多个科目的课程中注册。v_Enrollments 视图返回完整的学生列表 (NetId) 和他们正在学习的课程的主题 (Subj)。

出于会计原因,我需要将每个学生分配到一个且只有一个部门(基于班级主题)。如果他们在不同科目上多门课,优先级基于科目数。如果他们在不同科目上相同数量的课程,那么平局会随机(伪)打破。

我不熟悉窗口功能,并且有点想出一个解决方案。下面的查询有效,但我不禁想知道是否有更好的解决方案。

select NetId, Subj
from (
    select NetId, Subj, RowNum
        , Max(RowNum) Over (partition by NetId) as MaxRowNum
    from (
        select NetId, Subj
            , Count(*) as Cnt
            , MAX(Count(*)) Over(partition by NetId) as MaxCnt
            , ROW_NUMBER() Over (partition by NetId order by checksum(NetId, Subj)) as RowNum
                                                    -- psuedorandom but repeatable ordering
        from v_Enrollment
        group by NetId, Subj
    ) as s2
    where Cnt = MaxCnt
) as s1
where RowNum = MaxRowNum
order by NetId

标签: sqlsql-servertsqlwindow-functions

解决方案


我想不需要这么多操作。可以这样做:

WITH DataSource AS
(
    SELECT NetId
          ,Subj
          ,COUNT(*) AS CntClasses
    FROM v_Enrollment
    GROUP BY NetId
            ,Subj
), 
DataSourceOrdered AS
(
    SELECT NetId
          ,Subj
          ,ROW_NUMBER() OVER (ORDER BY CntClasses DESC, checksum(NetId, Subj)) AS [RowID]
    FROM DataSource
)
SELECT *
FROM DataSourceOrdered
WHERE [RowID] = 1
ORDER BY NetId;

我们需要知道每个学生-科目对的班级数量。然后根据您的条件使用一个ROW_NUMBER来订购科目 - 更高的班级计数,然后是您的随机数。完成此操作后,只需获取带有[RowID] = 1.


推荐阅读