Reputation: 21
How would you improve the following query in SQL Server to find in which of the courses the men/women ratio is over 70%? (I added a diagram of all tables related..not all of them are necessary)
SELECT
F.CourseId,
CAST(ROUND(CAST(M.Men AS FLOAT) / CAST(F.Women AS FLOAT) * 100, 2) AS NUMERIC(12, 2)) AS Ratio
FROM
(SELECT
c.CourseId, COUNT(DISTINCT c.StudentId) AS Women
FROM
Classrooms c
INNER JOIN
Students s ON c.StudentId = s.StudentId
WHERE
s.Gender = 'F'
GROUP BY
c.CourseId) F
INNER JOIN
(SELECT
c.CourseId, COUNT(DISTINCT c.StudentId) AS Men
FROM
Classrooms c
INNER JOIN
Students s ON c.StudentId = s.StudentId
WHERE
s.Gender = 'M'
GROUP BY
c.CourseId) M ON F.CourseId = M.CourseId
WHERE
CAST(M.Men AS FLOAT) / CAST(F.Women AS FLOAT) * 100 > 70
ORDER BY
F.CourseId
I want to practice effective and shorter (better) queries.
Thank you all!
Upvotes: 0
Views: 48
Reputation: 10163
You can use single query like:
SELECT
c.CourseId,
COUNT(DISTINCT CASE WHEN s.Gender = 'F' THEN c.StudentId ELSE NULL END) AS Women,
COUNT(DISTINCT CASE WHEN s.Gender = 'M' THEN c.StudentId ELSE NULL END) AS Man,
CAST(COUNT(DISTINCT CASE WHEN s.Gender = 'M' THEN c.StudentId ELSE NULL END) AS FLOAT) / COUNT(DISTINCT c.StudentId) AS MensRate
FROM Classrooms c
INNER JOIN Students s ON c.StudentId = s.StudentId
GROUP BY c.CourseId
HAVING CAST(COUNT(DISTINCT CASE WHEN s.Gender = 'M' THEN c.StudentId ELSE NULL END) AS FLOAT) / COUNT(DISTINCT c.StudentId) > 0.7
A mean you should to divide Men's count to total count for rate calculate.
Upvotes: 1