1、前言
前面的內容已經把基礎的增刪改查介紹的差不多了,也介紹了表格的相關約束, 從本期開始往後的內容,就更加複雜了,更多的是一些複雜的查詢SQL.
2、插入查詢結果
查詢還是用的比較多的,對於查詢到的數據,能不能也給保存下來?也就是把查詢的結果插入到另一張表中。
案例:創建一張學生表,表中有id,name,sex,java,python 這些字段,現在需要把java 成績超過90 的學生複製進java_result 表,複製的字段為name,java 。
進行上述操作之前,我們需要建立一個學生表並準備好相關的資料:
create table student ( id int primary key, name varchar(20), sex varchar(1), java float(5, 2) ); insert into student value (1, '张三', '男', 92.1), (2, '小红', '女', 88.2), (3, '赵六', '男', 83.4), (4, '王五', '男', 93.3), (5, '小美', '女', 96.0);
有了學生表之後,我們要把name,java 這兩個欄位的查詢結果複製到java_result 這個表中,這裡我們注意,要求查詢結果的臨時表的列數和列的類型,要和java_result 這裡匹配,所以接下來我們就來創建java_result 這張表:
create table java_result ( name varchar(20), java float(5, 2) );
創建好java_result 這張表之後,就要查詢student 表中name java 兩個字段,並且java > 90,將滿足上述條件的查詢結果,插入到java_result 表中! :
insert into java_result select name, java from student where java > 90; -- Query OK, 3 rows affected (0.00 sec) -- Records: 3 Duplicates: 0 Warnings: 0
select * from java_result; +--------+-------+ | name | java | +--------+-------+ | 张三 | 92.10 | | 王五 | 93.30 | | 小美 | 96.00 | +--------+-------+ -- 3 rows in set (0.00 sec)
這樣我們就發現,已經將 student 表中 name 和 java 欄位滿足 > 90 的資料已經全部插入成功了!
3、聚合查詢
前面我們接觸過的 帶表達式查詢 都是列和列之間進行運算的,看哪一列滿足了這個條件。
而現在要介紹的聚合查詢,就是針對 行和行 之間進行運算的!
3.1 聚合函數
要進行聚合查詢,必須使用聚合函數。下面介紹的函數都是SQL 內建的一組函數,讓我們先來簡單了解它們
#函數 | |
---|---|
COUNT([DISTINCT] expr) | #傳回查詢到的資料的數量 |
##SUM([DISTINCT] expr ) | 傳回查詢到的資料的總和,不是數字無意義 |
下面我们就来演示一下上述的聚合函数的简单使用,在使用之前,我们需要有一张表,并且有相应的数据:
select * from student; +----+--------+------+-------+ | id | name | sex | java | +----+--------+------+-------+ | 1 | 张三 | 男 | 92.10 | | 2 | 小红 | 女 | 88.20 | | 3 | 赵六 | 男 | 83.40 | | 4 | 王五 | 男 | 93.30 | | 5 | 小美 | 女 | 96.00 | | 6 | 李四 | 男 | NULL | +----+--------+------+-------+ -- 6 rows in set (0.00 sec)
下面我们就针对上述这张表,来使用下上述的聚合函数。
3.1.1 count
● 求出 student 表中有多少同学
select count(*) from student; +----------+ | count(*) | +----------+ | 6 | +----------+ -- 1 row in set (0.00 sec)
这个操作就相当于先进行 select * ,然后针对返回的结果,在进行 count 运算,求结果集合的行数. 注意:此处如果有一列的数据全是 null,也会算进去!(因为是针对 *)
此处这里的 count() 括号中,不一定写 *,可以写成任意的列明/表达式,所以我们可以针对 name 来统计人数:
select count(name) from student; +-------------+ | count(name) | +-------------+ | 6 | +-------------+ -- 1 row in set (0.00 sec)
● 统计有多少人有 java 考试成绩
select count(java) from student; +-------------+ | count(java) | +-------------+ | 5 | +-------------+ -- 1 row in set (0.00 sec)
这里我们看到了,由于 count 是针对 java 字段进行统计,而 李四 那一条数据中,java 为 null,前面我们学习过,null 与任何值计算都是 null,所以统计的时候,就把 null 给去掉了。
● 统计 java 成绩大于90分的人数
select count(java) from student where java > 90; +-------------+ | count(java) | +-------------+ | 3 | +-------------+ -- 1 row in set (0.00 sec)
这里我们要弄清楚,count() 这个括号中,是针对你要针对的那一列,针对不同列,不同的条件,就会有不同的结果,对于 count 的演示就到这里。
注意:count 和 () 之间不能有空格,必须紧挨着,在 Java 中函数名和() 之间是可以有空格的,但很少人会这样写。
3.1.2 sum
这个聚合函数,就是把指定列的所有行进行相加得到的结果,要求这个列得是数字,不能是字符串/日期。
● 求出学生表中 java 考试分数总和
select sum(java) from student; +-----------+ | sum(java) | +-----------+ | 453.00 | +-----------+ -- 1 row in set (0.01 sec)
虽然我们表中有 java 字段这列中有 null 值,前面了解到 null 与任何值运算都是 null,但是这里的 sum 函数会避免这种情况发生。
当然在后面也可也带上 where 条件,这里就不做过多演示了。
3.1.3 avg
● 求班级中 java 的平均分
select avg(java) from student; +-----------+ | avg(java) | +-----------+ | 90.600000 | +-----------+ -- 1 row in set (0.00 sec)
当前只是针对某一列进行平均运算,如果有两门课程,求每个学生总分的平均分呢?
select avg(java + python) from student;
这里每次查询结果都只有一列,能否把两个聚合函数一起使用呢?
select sum(java), avg(java) as '平均分' from student; +-----------+-----------+ | sum(java) | 平均分 | +-----------+-----------+ | 453.00 | 90.600000 | +-----------+-----------+ -- 1 row in set (0.00 sec)
这里我们能发现一个细节,使用聚合函数查询,字段也是可以取别名的。
3.1.4 max 和 min
● 求出 java 考试分数的最高分和最低分
select max(java) as '最高分', min(java) as '最低分' from student; +-----------+-----------+ | 最高分 | 最低分 | +-----------+-----------+ | 96.00 | 83.40 | +-----------+-----------+ -- 1 row in set (0.00 sec)
上述就是聚合函数最基础的用法了, 但是在实际中也可能会有更复杂的情况,比如需要按照某某进行分组查询,这就需要搭配 GROUP BY 字句了。
4、GROUP BY 子句
select 中使用 group by 自居可以对指定列进行分组查询,但是需要满足指定分组的字段必须是 "分组依据字段",其他字段若想出现在 select 中,则必须包含在聚合函数中。
这里我们构造出一张薪水表 salary:
create table salary ( id int primary key, name varchar(20), role varchar(20), income int ); insert into salary value (1, '麻花疼', '老板', 5000000), (2, '篮球哥', '程序猿', 3000), (3, '歪嘴猴', '经理', 20000), (4, '多嘴鸟', '经理', 25000), (5, '雷小君', '老板', 3000000), (6, '阿紫姐', '程序猿', 5000);
像上述的情况,如果要查平均工资,那公平吗???
select avg(income) from salary; +--------------+ | avg(income) | +--------------+ | 1342166.6667 | +--------------+ -- 1 row in set (0.00 sec)
那篮球哥的月薪连平均下来的零头都不到,所以这样去求平均工资是毫无意义的,真正有意义的是啥呢?求老板这个职位的平均工资,以及经理这个职位的平均工资,及程序猿这个职位的平均工资,通俗来说,就是按照 role 这个字段进行分组。每一组求平均工资:
select role, avg(income) from salary group by role; +-----------+--------------+ | role | avg(income) | +-----------+--------------+ | 程序猿 | 4000.0000 | | 经理 | 22500.0000 | | 老板 | 4000000.0000 | +-----------+--------------+ -- 3 rows in set (0.00 sec)
此句可以重写为:这是将role列中值相同的行分为一组,然后按组计算平均值,也是针对每个组分别计算。
在 MySQL 中,这里得到的查询结果临时表,如果没有 order by 指定列排序,这里的顺序是不可预期的,当然也可以手动指定排序,比如最终结果按照平均工资降序排序:
select role, avg(income) from salary group by role order by avg(income) desc; +-----------+--------------+ | role | avg(income) | +-----------+--------------+ | 老板 | 4000000.0000 | | 经理 | 22500.0000 | | 程序猿 | 4000.0000 | +-----------+--------------+ -- 3 rows in set (0.00 sec)
如果不带聚合函数的普通查询,能否可行呢?这里如果你没有修改任何配置文件,是不可行的,记住千万不能把前面的 order by 与 group by 弄混!
5、HAVING 关键字
分组查询也是可以指定条件的,具体三种情况:
先筛选,再分组(where)
先分组,再筛选(having)
分组前分组后都指定条件筛选(where 和 having 结合使用)
如何理解上述三条的含义呢? 这里我们举几个例子就很好理解了:
● 篮球哥月薪 3000 实在是太低了,简直给程序猿岗位拖后腿,干脆求平均工资时去掉篮球哥的月薪数据。
select role, avg(income) from salary where name != '篮球哥' group by role; +-----------+--------------+ | role | avg(income) | +-----------+--------------+ | 程序猿 | 5000.0000 | | 经理 | 22500.0000 | | 老板 | 4000000.0000 | +-----------+--------------+ -- 3 rows in set (0.00 sec)
这样求出来的平均值就不包含篮球哥的月薪数据了,这就是先筛选,再分组。
● 还是查询每个岗位的平均工资,但是除去平均月薪在 10w 以上的岗位,不能让篮球哥眼红!
select role, avg(income) from salary group by role having avg(income) < 100000; +-----------+-------------+ | role | avg(income) | +-----------+-------------+ | 程序猿 | 4000.0000 | | 经理 | 22500.0000 | +-----------+-------------+ -- 2 rows in set (0.00 sec)
这样一来就只保留了平均月薪小于 10w 的岗位了,很明显这个平均值是在分组之后才算出来的,这也就是先分组,再筛选。
这里 having 也能加上逻辑运算符,具体感兴趣的小伙伴可以自行下来尝试一下,好比如你想要拿好 offer,就得技术过关,还能加班!至于第三种分组前后都需要筛选,就是把上述俩例子结合起来,这里就不多赘述了!
以上是MySQL聚合查詢方法怎麼使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

MySQL索引基数对查询性能有显著影响:1.高基数索引能更有效地缩小数据范围,提高查询效率;2.低基数索引可能导致全表扫描,降低查询性能;3.在联合索引中,应将高基数列放在前面以优化查询。

MySQL學習路徑包括基礎知識、核心概念、使用示例和優化技巧。 1)了解表、行、列、SQL查詢等基礎概念。 2)學習MySQL的定義、工作原理和優勢。 3)掌握基本CRUD操作和高級用法,如索引和存儲過程。 4)熟悉常見錯誤調試和性能優化建議,如合理使用索引和優化查詢。通過這些步驟,你將全面掌握MySQL的使用和優化。

MySQL在現實世界的應用包括基礎數據庫設計和復雜查詢優化。 1)基本用法:用於存儲和管理用戶數據,如插入、查詢、更新和刪除用戶信息。 2)高級用法:處理複雜業務邏輯,如電子商務平台的訂單和庫存管理。 3)性能優化:通過合理使用索引、分區表和查詢緩存來提升性能。

MySQL中的SQL命令可以分為DDL、DML、DQL、DCL等類別,用於創建、修改、刪除數據庫和表,插入、更新、刪除數據,以及執行複雜的查詢操作。 1.基本用法包括CREATETABLE創建表、INSERTINTO插入數據和SELECT查詢數據。 2.高級用法涉及JOIN進行表聯接、子查詢和GROUPBY進行數據聚合。 3.常見錯誤如語法錯誤、數據類型不匹配和權限問題可以通過語法檢查、數據類型轉換和權限管理來調試。 4.性能優化建議包括使用索引、避免全表掃描、優化JOIN操作和使用事務來保證數據一致性

InnoDB通過undolog實現原子性,通過鎖機制和MVCC實現一致性和隔離性,通過redolog實現持久性。 1)原子性:使用undolog記錄原始數據,確保事務可回滾。 2)一致性:通過行級鎖和MVCC確保數據一致。 3)隔離性:支持多種隔離級別,默認使用REPEATABLEREAD。 4)持久性:使用redolog記錄修改,確保數據持久保存。

MySQL在數據庫和編程中的地位非常重要,它是一個開源的關係型數據庫管理系統,廣泛應用於各種應用場景。 1)MySQL提供高效的數據存儲、組織和檢索功能,支持Web、移動和企業級系統。 2)它使用客戶端-服務器架構,支持多種存儲引擎和索引優化。 3)基本用法包括創建表和插入數據,高級用法涉及多表JOIN和復雜查詢。 4)常見問題如SQL語法錯誤和性能問題可以通過EXPLAIN命令和慢查詢日誌調試。 5)性能優化方法包括合理使用索引、優化查詢和使用緩存,最佳實踐包括使用事務和PreparedStatemen

MySQL適合小型和大型企業。 1)小型企業可使用MySQL進行基本數據管理,如存儲客戶信息。 2)大型企業可利用MySQL處理海量數據和復雜業務邏輯,優化查詢性能和事務處理。

InnoDB通過Next-KeyLocking機制有效防止幻讀。 1)Next-KeyLocking結合行鎖和間隙鎖,鎖定記錄及其間隙,防止新記錄插入。 2)在實際應用中,通過優化查詢和調整隔離級別,可以減少鎖競爭,提高並發性能。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

Atom編輯器mac版下載
最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

禪工作室 13.0.1
強大的PHP整合開發環境