0

Need suggestions on a MS SQL query:

table: students

id  name    class
--  ----    -----
1   John    Math, Biology
2   Jane    English
3   Mark    Math

table: class

id  name
--  ----
1   Math
2   English
3   Biology
4   History

Desired output

name        count
----        -----
Math        2
English     1
Biology     1
History     0
1
  • So you have a string column called class and in it you need to parse the comma list to get the class names? I notice in your example Science doesn't appear anywhere except in the Students table. Is that a bug or do you really not what that result? Commented Feb 27, 2013 at 16:29

3 Answers 3

2

This is for MySQL.

SELECT  a.name, COUNT(b.id) as `totalCount`
FROM    class a
        LEFT JOIN students b
            ON FIND_IN_SET(a.name, b.class) > 0
GROUP   BY a.name

for best performance, normalize the tables such by creating 3 tables,

students

  • ID (PK)
  • Name

Class

  • ID (PK)
  • Name

StudentClass

  • StudentID (FK)
  • ClassID (FK)

This is a many-to-many relationship since students may have many classes while classes have also have many students.

And the query should look like this,

SELECT  a.Name, COUNT(b.ClassID) totalCount
FROM    Class a
        LEFT JOIN StudentClass b
          ON a.id = b.ClassID
GROUP   BY a.Name
Sign up to request clarification or add additional context in comments.

4 Comments

@JW find_in_set is not a recognized built-in function name.. Im using MS SQL
@Sable Foste ... I have no control on the DB
What RDBMS you are using? RDBMS stands for Relational Database Management System. RDBMS is the basis for SQL, and for all modern database systems like MS SQL Server, IBM DB2, Oracle, MySQL, etc...
if that's the case, see @GordonLinoff 's answer.
1

Here is the answer for SQL Server:

SELECT  c.name, COUNT(b.id) as `totalCount`
FROM class c LEFT JOIN
     students s
     ON ','+s.class+',' like '%,'+a.name+',%'
GROUP BY c.name

Actually, that doesn't work well with the spaces that you have in the class names. Try this on instead:

     ON ','+replace(s.class, ' ', '')+',' like '%,'+replace(a.name, ' ', '')+',%'

2 Comments

I had to use this though: ON s.class like '%'+a.name+'%'
@FlipBooth . . . That works. Until you have a class name called "English" and another called "English Literature".
1
select 
class.name as name, 
count(*) as count 
from students, class 
where students.class like '%'+class.name+'%' 

1 Comment

This won't work because it will not return classes with 0 count

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.