mysql 聚集函數 count 使用詳解


mysql 聚集函數 count 使用詳解

本文將探討以下問題

1.count(*) 、 count(n)、count(null)與count(fieldName)
2.distinct 與 count 連用
3.group by (多個字段) 與 count 實現分組計數
4.case when 語句與 count 連用實現按過濾計數

參考文章:
Select count(*)和Count(1)的區別和執行方式

准備工作

-- 創建表
CREATE TABLE `tb_student` (
  `id` int(11) NOT NULL,
  `stu_name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '學生姓名',
  `tea_name` varchar(255) DEFAULT NULL COMMENT '教師姓名',
  `stu_class` varchar(255) DEFAULT NULL COMMENT '所在班級名稱',
  `stu_sex` varchar(255) DEFAULT NULL COMMENT '學生性別',
  `stu_sex_int` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入數據 
INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('0', '小明', '老張', '一班', '男',0);
INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('1', '小紅', '老張', '一班', '女',0);
INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('2', '小剛', '老王', '一班', '男',0);
INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('3', '小蘭', '老王', '一班', '女',0);
INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('4', '小軍', '老張', '二班', '男',0);
INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('5', '小芳', '老張', '二班', '女',0);
INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('6', '小強', '老王', '二班', '男',0);
INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('7', '小娜', '老王', '二班', '女',0);
INSERT INTO `tb_student` (`id`, `stu_name`, `tea_name`, `stu_class`, `stu_sex`) VALUES ('8', null, null, null, null,null);

問題一:count(*) 、 count(n)、count(null)與count(fieldName)

我們看一下執行過程:
EXPLAIN SELECT count(0) from tb_student
EXPLAIN SELECT count(*) from tb_student
**兩次執行結果相同,結果為: **
(select_type, table, type, possible_keys, key, key_len, ref, rows, Extra) VALUES ('1', 'SIMPLE', 'tb_student', 'index', NULL, 'stu_sex_int', '2', NULL, '8', 'Using index');
此次查詢使用了索引stu_sex_int。我們知道某個字段建立索引之后數據庫引擎會對該字段排序並把排序結果作為索引數據存儲。查詢時候對索引進行
二分查找提高命中率。在使用聚集函數同樣也會使用索引。數據庫引擎在處理count時,會直接從索引數據(排序結果中)中求排序結果的id最大值。這樣一
來會大大提高count的速度。主鍵也有索引此處為什么沒有使用主鍵的索引?因為stu_sex_int 字段長度更短 為tinyint 類型,查找速度更快。
由此可見 count(*)和count(n) n>=0 的效果相同。
當count的表達式為 NULL 時 不會計數 ,所以count(fieldName) 當fieldName 為null時 不會計數 。比如

  • select count(stu_name) as count from tb_student; 結果: count=8
  • select count(id) as count from tb_student; 結果: count=9
  • select count(null) as count from tb_student ; 結果: count= 0

問題二: distinct 與 count 連用

distinct 的作用是對查詢結果去重。distinct fieldA 那么在查詢結果中 fieldA 的值不會重復。當 count 內的表達式是distinct時候
所表達的意思就是對被distinct的字段取值類型計。例如:

select distinct stu_class from tb_student;

執行結果:

stu_class
一班
二班

select count(distinct stu_class) as count from tb_student;
執行結果:

count
2

問題三:group by (多個字段) 與 count 實現分組計數

group by fieldA 是表示根據 fieldA 的不同取值對查詢結果進行分組。比如對於 tb_student
根據 stu_sex 的不同取值 (男,女) 可把查詢結果分成兩組。fieldA 有n個不同的取值,查詢結果就會被分成
n組。當分組字段有多個時候group by fieldA,fieldB 會對fieldA 和fieldB 進行排列組合。每個排列組合的
結果作為查詢一個的一個分組。如果fileA 的取值有 n 個 fieldB的取值有 m 個,那么查詢結果 將會被分稱m*n
組。當count 與 group by 連用時,count是對 group by 結果的各個分組進行計數 。
單個分組條件:
SELECT stu_sex ,COUNT(*) as count from tb_student GROUP BY stu_sex ;
結果為:

stu_sex count
NULL 1
4
4

多個分組條件:

    SELECT
        stu_sex,
        stu_class,
        COUNT(*) AS count
    FROM
        tb_student
    GROUP BY
        stu_sex,
        stu_class

結果為:

stu_sex stu_class count
NULL NULL 1
一班 2
二班 2
一班 2
二班 2

問題四:case when 語句與 count 連用實現按過濾計數

在上述數據庫中如果我們要查每個教師教了多少個 一班 同學 和二班同學 有兩種方法
方法一:對教師和班級分組計數

      SELECT
        tea_name,
        stu_class,
        count(*) AS count
      FROM
        tb_student
      GROUP BY
        tea_name,
        stu_class

結果為:

tea_name stu_class count
NULL NULL 1
老張 一班 2
老張 二班 2
老王 一班 2
老王 二班 2

這種方法不太直觀我們可以把結果行轉列更加清晰表達每個教師交每個班的人數

方法二:使用case when 行轉列

      SELECT
      	tea_name,
      	count(case when stu_class='一班' then 1 else null end ) AS `一班人數` ,
        count(case when stu_class='二班' then 1 else null end ) AS `一班人數` 
      FROM
      	tb_student
      GROUP BY
      	tea_name

結果為:

tea_name 一班人數 一班人數
NULL 0 0
老張 2 2
老王 2 2

當關注的計數屬性有較多取值時不適合這種用法,比如有100個班級,我們無法去寫100個case when 。

文中的不足、錯誤之處歡迎指正


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM