SQL Server模式SQL

3
我有一张表格,列出了每个班级学生的成绩。 我希望得到一个结果集,看起来像这样:
BIO...B
CHEM...C

这里的“B”和“C”是指班级的模式。 我可以获得所有成绩的模式,但不确定如何获得每个班级的模式。


2
如果从统计意义上来说,那不是众数。众数是出现最频繁的元素。在这种情况下,你的两个类别都是双峰的(生物学中的A、C和化学中的B、D)。 - Tom H
我使用的结果集与我使用的示例表值无关。 - bmw0128
那么你真的想要这个模式吗?还是说,你在寻找你的示例所显示的平均数或中位数(由于有两个值,很难确定)? - Austin Salonen
我想要求出每个类别中出现最频繁的众数。 - bmw0128
我正在使用MS SQL Server,没有内置的MODE()函数。 - bmw0128
显示剩余3条评论
2个回答

5

这里是关于SQL 2005/2008的内容:

;WITH 
  Counts AS (
    SELECT ClassName, Grade, COUNT(*) AS GradeFreq 
    FROM Scores
    GROUP BY ClassName, Grade
    )
, Ranked AS (
    SELECT ClassName, Grade, GradeFreq
    , Ranking = DENSE_RANK() OVER (PARTITION BY ClassName ORDER BY GradeFreq DESC)
    FROM Counts
    )
SELECT * FROM Ranked WHERE Ranking = 1

或者只是:
;WITH Ranked AS (
  SELECT 
    ClassName, Grade
  , GradeFreq = COUNT(*)
  , Ranking = DENSE_RANK() OVER (PARTITION BY ClassName ORDER BY COUNT(*) DESC)
  FROM Scores
  GROUP BY ClassName, Grade
  )
SELECT * FROM Ranked WHERE Ranking = 1

谢谢,这样就可以了,但我正在研究如何编写UDF。 - bmw0128

2

使用GROUP BY子句。

SELECT className, ClassMode(className)
FROM Grades
GROUP BY className

您的 Mode() 函数当然需要被创建,但它只是一个简单的函数,例如:

CREATE FUNCTION ClassMode(@ClassName varchar(50))
RETURNS varchar(2)
AS
BEGIN
    Declare @temp varchar(2)

    SELECT @temp = TOP 1 Grade, COUNT(*) Grades as frequency
    FROM Grades
    WHERE ClassName = @ClassName
    GROUP BY ClassName
    ORDER BY frequency DESC

    RETURN @temp
END

函数代码中似乎有些东西丢失了,是吗?好像根本没有使用@ClassName。我认为应该将FROM子句更改为"FROM Grades where ClassName = @ClassName"或将GROUP BY子句更改为GROUP BY ClassName HAVING ClassName = @ClassName。此外,在主函数中,SELECT可以简单地选择Select distinct ClassName, ClassMode(ClassName) from Grades。这样,每个ClassName只有一个模式。或者我理解错了吗? - Wagner Silveira
感谢您在函数定义上的指正 - 明显缺少了where/having。至于distinct,您肯定可以这样做 - 我认为OP将会按学生进行操作,因此我怀疑那个简单的查询无法完成他们需要的任务,但对于给定的示例,您是正确的。 - womp
我需要每个类的模式,所以你是说我需要修改这个UDF才能使它工作? - bmw0128

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接