2010-01-11 96 views
2

我有一张表列出了每个班级学生的成绩。 我想要的结果集看起来像:SQL Server模式SQL

BIO...B 
CHEM...C 

其中“B”和“C”是该类的模式。 我可以得到所有等级的方式,但不知道如何让每类模式

+2

这不是模式,如果你是在统计意义上说话。模式是最常出现的元素。在这种情况下,你的两个类都是双模态的(A,C代表Bio和B,D代表Chem) – 2010-01-11 21:29:33

+0

我使用的结果集与我使用的示例表值无关 – bmw0128 2010-01-11 21:35:03

+0

那么你真的想要模式吗?或者,您是否在寻找您的示例显示的平均值或中值(难以用两个值来判断)? – 2010-01-11 21:38:08

回答

4

这里,像这样的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 
+0

谢谢,这将做到这一点,但我正在研究如何做一个UDF – bmw0128 2010-01-11 22:36:09

0

你只需要GROUP BY ClassName

SELECT ClassName, MODE(Grade) FROM YourTable GROUP BY ClassName 
+1

SQL Server有一个Mode()函数吗? – bmw0128 2010-01-11 21:35:40

+0

你可以很容易地写一个。 – JonH 2010-01-11 21:41:13

+0

我是这方面的新人,不知道我能不能找到自己的自定义函数的位置,以便我的SQL调用它可以找到它? – bmw0128 2010-01-11 21:43:53

2

,如果您想要的模式,一个解决方案是在这里:

http://oreilly.com/catalog/transqlcook/chapter/ch08.html 
"Calculating a Mode" 

,如果你想在中间,看看在SQL Server此解决方案:

http://oreilly.com/catalog/transqlcook/chapter/ch08.html 
scroll to "Calculating a Median" 

其他解决方案获得中位数:

http://www.sqlmag.com/Files/09/49872/Listing_05.txt 
http://www.tek-tips.com/faqs.cfm?fid=4751 
+0

为什么avg ?,我正在寻找模式? – bmw0128 2010-01-11 21:38:02

+1

这些oreilly链接不再工作 – Slider345 2015-05-20 20:16:45

2

使用GROUP BY子句。

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

你的模式()函数将不得不当然被创建,但它会像一个简单的函数:

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 
+0

功能代码中缺少某些东西不是吗?看起来好像@ClassName根本不用。我认为它应该将FROM子句变为“FROM Grades where ClassName = @ClassName”或将GROUP BY子句变为GROUP BY ClassName HAVING ClassName = @ClassName。 另外,主要中的SELECT可以简单地从Grades中选择不同的ClassName,ClassMode(ClassName)。这样您每个ClassName都有一个模式。还是我得到这个错误? – 2010-01-11 22:01:01

+0

感谢您对函数定义的理解 - 绝对错过了where/having。至于截然不同的情况,你可以肯定做到这一点 - 我在OP的印象中会给每个学生做这件事,所以我怀疑这个简单的查询会完成他们需要的东西,但是对于给定的例子你是正确的。 – womp 2010-01-11 22:30:11

+0

我需要每班的模式,所以你说我需要修改这个UDF使它工作? – bmw0128 2010-01-11 22:44:07