1. 程式人生 > 資料庫 >MySQL 求眾數、稀疏數

MySQL 求眾數、稀疏數

資料表

假設有 student 表,資料如下:

+----+------+-------+
| id | name | score |
+----+------+-------+
|  1 | 劉備     |    90 |
|  2 | 曹操    |    90 |
|  3 | 孫權    |    90 |
|  4 | 劉表     |    50 |
|  5 | 劉封     |    30 |
|  6 | 張飛    |  NULL |
+----+------+-------+

建表語句如下:

+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

| Table   | Create Table                                                                                                                                                                                               |
+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student | CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  `score` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 |
+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

問題 1 :求出現次數最多的分數、出現次數最少的分數

  (1)select score from student where score is not null group by score order by count(*) desc limit 1; -- 出現次數最多的分數

+-------+
| score |
+-------+
|    90 |
+-------+

  (2)select score from student where score is not null group by score order by count(*) asc limit 1; -- 出現次數最少的分數

+-------+
| score |
+-------+
|    50 |
+-------+

問題 2:求出現次數最多的姓、出現次數最少的姓

  (1)select left(name,1) from student group by left(name,1) order by count(*) desc limit 1; -- 出現次數最多的姓

+--------------+
| left(name,1) |
+--------------+
| 劉             |
+--------------+

(2)select left(name,1) from student group by left(name,1) order by count(*) asc limit 1; -- 出現次數最少的姓

+--------------+
| left(name,1) |
+--------------+
| 曹             |
+--------------+

問題 3:求出現次數最多的分數區間( 劃分為兩個區間[0, 60)、[60, 100] ,還可以劃分的更細,這裡只劃分為 2 個)、出現次數最少的分數區間

  (1) select if(score<60,'[0, 60)','[60, 100]') from student where score is not null group by if(score<60,'[0, 60)','[60, 100]') order by count(*) desc limit 1; -- 出現次數最多的分數區間

+------------------------------------+
| if(score<60,'[0, 60)','[60, 100]') |
+------------------------------------+
| [60, 100]                          |
+------------------------------------+

(2) select if(score<60,'[0, 60)','[60, 100]') from student where score is not null group by if(score<60,'[0, 60)','[60, 100]') order by count(*) asc limit 1;-- 出現次數最少的分數區間

+------------------------------------+
| if(score<60,'[0, 60)','[60, 100]') |
+------------------------------------+
| [0, 60)                            |
+------------------------------------+

缺陷及改正

其實、眾數或稀疏數可能有多個,比如問題 2 中的出現次數最少的姓名不知一個,包括 孫、張、曹。

考慮到這種情況的 sql 應該這麼寫:

select left(name, 1) from student group by left(name, 1) having count(*) = (select count(*) from student group by left(name,1) order by count(*) asc limit 1);

執行 sql,得到結果集

+---------------+
| left(name, 1) |
+---------------+
| 孫              |
| 張              |
| 曹              |
+---------------+

其他問題中的情況類似。