简体   繁体   中英

How to Compare COUNT of Groups in Percentage in SQL?

I really new to SQL, currently learning PostgreSQL.

Suppose I have the following schema:

class(class_id, school_name) , primary key: (class_id)

enroll(student_id, class_id) , primary key: (student_id, class_id)

I want to find the class_id where the class' sum of enrolled student is at least 10% higher than average.

I know that I can find sum of enrollment for any class by

SELECT E.class_id, COUNT(*)
FROM enroll E
GROUP BY E.class_id

But how do I compare one to the other in percentage?

here's your query, you can use avg() and having clause

select t1.class_id, t1.ct 
from
    (select count(1)ct, class_id
    from enroll 
    group by class_id) t1
group by t1.class_id
having avg(t1.ct) > (t1.ct * .10)

Based on your scenario I have tried something like below.

I have Created two demo schemas as below.

CREATE TABLE #class
(
    class_id INT PRImARY KEY IDENTITY(1,1),
    school_name NVARCHAR(MAX)
)
CREATE TABLE #enroll
(
    student_id INT,
    class_id INT,
    CONSTRAINT [student_class] PRIMARY KEY CLUSTERED (student_id, class_id) 
)

INSERT INTO #class(school_name) VALUES('A'),('B'),('C'),('D')

INSERT INTO #enroll(student_id,class_id)
VALUES(1,1),(2,1),(3,1),(4,2),(5,2),(6,2),(7,3),(8,3),(9,4)

SELECT C.school_name,CONCAT(AVG(E.Student_id),'%') AS  Normal ,
AVG(E.Student_id * .10) AS TenPercentageAvg,COUNT(E.Student_id) AS TotalStudent,
CAST(AVG(E.Student_id) + AVG(E.Student_id * .10) AS DECIMAL(10,2)) AS SumOFTenPercentageAvg
FROM #enroll E
INNER JOIN #class  C ON  C.class_id = E.class_id
GROUP BY C.school_name
HAVING  COUNT(E.Student_id) >= CAST(AVG(E.Student_id) + AVG(E.Student_id * .10) AS DECIMAL(10,2))

I got result as below.

所有记录均值和计数

As the above image, you can see count with average data and sum with 10 percent.

Now the final result you can see below.

最后结果

I think you want:

select c.*
from (select class_id, count(*) as cnt,
             avg(count(*) over () as avg_cnt
      from enroll 
      group by class_id
     ) c
where cnt > avg_cnt * 1.1;

The average is calculated by taking the average over all the classes using a window function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM