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

Posted

技术标签:

【中文标题】根据计数对记录集进行分类【英文标题】:Classifying recordsets based on counts 【发布时间】:2019-10-09 16:32:56 【问题描述】:

我的学生不是被录取,就是被另一所学校录取,但就读于一门或多门课程或我们的一门或多门课程。 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】:

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

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 的行。

【讨论】:

这就是我想要的。根本不需要Max。我的最终查询是 select NetId, Subj from ( select NetId, Subj , ROW_NUMBER() Over (partition by NetId order by Cnt desc, checksum(NetId, Subj)) as RowNum from ( select NetId, Subj, Count(*) as Cnt从 v_Enrollment group by NetId, Subj ) as s2 ) as s1 where RowNum = 1

以上是关于根据计数对记录集进行分类的主要内容,如果未能解决你的问题,请参考以下文章

从 mysql 获取大结果集

TSQL 根据提供的记录集获取以前的和任何进行的记录

SVM 与 openCV,对数据进行分类

在 Java 中对记录进行分类

SQL:计算每个设备集连续出现相同值的所有记录并返回最高计数

YOLOV7使用CADCD数据集实验记录