根据计数对记录集进行分类

时间:2019-10-09 16:32:56

标签: sql sql-server tsql window-functions

我有未入学或已入读另一所学校,但被一个或多个或我们课程中的一个或多个科目录取的学生。视图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

1 个答案:

答案 0 :(得分:1)

我想不需要这么多操作。可以通过以下方式完成:

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获取行。