views:

59

answers:

1

I have a student marks table with schema as given below:

Student
--------
SNO
Marks

I want to produce a result something as this:

MarksRange   Count
----------   ------
0             10
10             2
20             43
:              :
100            2

The above results shows that there are:

  • 10 students who got a score zero,
  • 2 students how got a score between 1 to 10,
  • 43 from 11-20
  • and so on.

Could anyone please let me know how to write a query which produces this result?

+5  A: 

try this:

DECLARE @Student table (SNO int,Marks int)

INSERT INTO @Student VALUES (1, 0)
INSERT INTO @Student VALUES (1, 3)
INSERT INTO @Student VALUES (1, 45)
INSERT INTO @Student VALUES (1, 95)
INSERT INTO @Student VALUES (1, 85)
INSERT INTO @Student VALUES (1, 97)
INSERT INTO @Student VALUES (1, 92)

DECLARE @StartNumber int
       ,@EndNumber   int
SELECT @StartNumber=0
      ,@EndNumber=100

;WITH AllNumbers AS
(
    SELECT @StartNumber AS Number
    UNION ALL
    SELECT Number+10
        FROM AllNumbers
        WHERE Number<@EndNumber
)
SELECT
    n.number AS MarksRange,COUNT(s.SNO) AS CountOf
    FROM AllNumbers               n
        LEFT OUTER JOIN @Student  s ON s.Marks=n.Number OR (s.Marks>n.Number-10 AND s.Marks<=n.Number)
    GROUP BY n.number

OUTPUT:

MarksRange  CountOf
----------- -----------
0           1
10          1
20          0
30          0
40          0
50          1
60          0
70          0
80          0
90          1
100         3

if you are not on SQL Server 2005+ you need to replace the CTE with a Numbers table. and use a query like:

SELECT
    n.number,COUNT(s.SNO),0 AS CountOf
    FROM Numbers                  n
        LEFT OUTER JOIN @Student  s ON s.Marks=n.Number OR (s.Marks>n.Number-10 AND s.Marks<=n.Number)
    WHERE n.Number>=@StartNumber AND n.Number<=@EndNumber AND CONVERT(decimal(3,1),n.Number/10)=n.Number/10.0
    GROUP BY n.number
KM
Perfect. Worked like a champ. Thanks a lot.
Mahesh