MYSQL--第三和第四章筆記
阿新 • • 發佈:2022-05-31
- # ORDER BY 排序資料
- # 如果沒有對錶進行排序操作,預設查詢是按新增的順序顯示
- SELECT * FROM employees;
- # 1、排序
- # 使用ORDER BY 對資料進行查詢操作
- # 升序:ASC
- # 降序:DESC
- # 如果在order by後面沒有指明排序方式,預設是升序排列ASC
- SELECT * FROM employees ORDER BY salary DESC;
- # 可以對列的別名,進行排序,order by列的別名不用加單引號
- SELECT department_id AS "部門編號",name AS "名字",
- salary AS "月工資",salary * 12 AS "年工資" FROM employees ORDER BY 年工資 DESC;
- # 注意:列的別名可以在order by中使用,不能在where中使用,否則會報錯!!
- # 注意:where要緊挨著from後面寫!!
- # 正確:SELECT * FROM employees WHERE salary IN (10000,8800) ORDER BY salary DESC;
- # 錯誤:SELECT * FROM employees ORDER BY salary DESC WHERE salary IN (10000,8800);
- # 二級排序
- # 先按照月工資進行排序,然後再按部門id進行排序
- SELECT * FROM employees ORDER BY salary DESC,department_id ASC;
- # 其他排序,和二級排序類似,可以類推
- # LIMIT 進行分頁顯示
- # LIMIT 偏移量,顯示條目數; 從偏移量+1到偏移量+顯示條目數 指標指向偏移量+1的位置
- SELECT * FROM employees LIMIT 0,20;-- 表示從 1到20
- # 每頁顯示pageSize條記錄,顯示第pageNo頁
- # LIMIT (pageNo - 1) * pageSize,pageSize;
- # SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT...
- # 正確:SELECT * FROM employees WHERE salary >= 9000 ORDER BY salary DESC LIMIT 0,20;
- # 報錯:SELECT * FROM employees WHERE salary >= 9000 LIMIT 0,20 ORDER BY salary;
- # 如果LIMIT的偏移量為0;可以寫成LIMIT 條目數,省略偏移量0
- SELECT * FROM employees WHERE salary >= 9000 ORDER BY salary DESC LIMIT 20;
- # mysql8.0新特性:LIMIT ... OFFSET ...
- # LIMIT 顯示條目數 OFFSET 偏移量;
- SELECT * FROM employees WHERE salary >= 7000 ORDER BY salary ASC LIMIT 30 OFFSET 0;
- # 擴充套件:LIMIT可以在MYSQL、PGSQL、MariaDB、SQLite等資料庫中使用,表示分頁,
- # 不能在SQL Sever、DB2、Oracle使用!!
- # 多表查詢
- # 如果把多張表的資料全放在一張表上,
- # 容易產生資料冗餘,以及IO的次數多影響效率,後期在維護上也很費力,不利於高併發的場景
- # 缺少連線條件:
- # 笛卡爾積錯誤:
- # SELECT department_id,name,city FROM employees,employees_detailed;
- # SELECT department_id,name,city FROM employees CROSS JOIN employees_detailed;
- # 錯誤產生的條件:
- # 省略多個表的連線條件(或關聯條件)
- # 連線條件(或關聯條件)無效
- # 所有表中的所有行互相連線
- -- 為了避免這種情況,可以在where加入有效的連線條件
- # 多表查詢的正確方式:需要連線條件
- # 列的別名不能再where中使用,但表的別名可以再where中使用!!
- SELECT * FROM employees AS e,employees_detailed AS ei
- WHERE e.location_id = ei.location_id;
- # 如果列名是多個表共有的列名,使用該列名時要用表名.列名來區分,建議都加表名!
- # 注意:如果在from上給表起了別名,就必須在select和where中用別名,不能用原名!!
- SELECT e.name as "名字",e.salary AS "月工資",ei.position AS "職位",et.type AS "狀態" ,
- e.location_id AS "e中的location",ei.location_id AS "ei中的location"
- FROM employees e,employees_detailed ei,employees_type et
- WHERE e.location_id = ei.location_id AND ei.age = et.age_detail;
- # 如果有n個表,需要至少n-1個連線條件!!!
- # 多表查詢的分類
- # 1、等值連線 vs 非等值連線
- # 2、自連線 vs 非自連線
- # 3、內連線 vs 外連線
- # 等值連線 vs 非等值連線(連線條件是大於、小於之類的。。。。)
- # 非等值連線:
- SELECT e.name AS "名字",e.salary AS "月工資",es.salary_low AS "等級下限",es.salary_high AS "等級上限",es.salary_grade AS "等級"
- FROM employees e,employees_slary es
- WHERE e.salary BETWEEN es.salary_low AND es.salary_high;-- WHERE中不能用列別名
- # 自連線(自己和自己連線) vs 非自連線
- # 自連線:
- # SELECT e.name AS "員工名字",em.name AS "員工上級名字",
- # e.salary AS"員工月工資",em.salary AS"員工上級月工資",
- # e.department_id AS "員工編號",em.department_id AS "員工上級編號",
- # e.manager_id AS "員工上級編號",em.manager AS "上級上級編號"
- # FROM employees e,employees em
- # WHERE e.manager_id = em.department_id;
- # 內連線 vs 外連線 有點類似集合 外連線的關鍵詞“所有”
- # 內連線:合併具有同一列的兩個以上的表的行,結果集中不包含一個表與另一個表不匹配的行,
- # 就是顯示符合連線條件的行,不顯示不符合連線條件的行(交集)
- # 外連線:合併具有同一列的兩個以上的表的行,結果集中除了包含一個表與另一個表匹配的行
- # 之外,還查詢了左表 或 右表中不匹配的行
- # 外連線的分類:左外連線 、 右外連線 、 滿外連線
- # 左外連線:合併具有同一列的兩個以上的表的行,結果集中除了包含一個表與另一個表匹配的行
- # 之外,還查詢了左表
- # 前面寫的基本都是sql92內連線寫法,mysql支援sql92的內連線寫法,不支援外連線寫法
- # 查詢所有員工的name和city的資訊(“所有”告訴要用外連線!)
- # SELECT e.name,ed.city FROM employees e,employees_detailed ed WHERE e.location_id(+) = ed.location_id;報錯因為mysql不支援sql92的外連線寫法
- # sql99的語法中使用join ... ON ...的方式實現多表的查詢,mysql支援sql99的內外連線語法
- # sql99的內連線寫法:
- SELECT e.department_id,e.`name`,e.sex,ed.city FROM employees e JOIN employees_detailed ed
- ON e.location_id = ed.location_id;-- 兩張表
- SELECT e.department_id,e.`name`,e.sex,ed.city,et.type FROM employees e JOIN employees_detailed ed
- ON e.location_id = ed.location_id JOIN employees_type et ON ed.age = et.age_detail;-- 多張表
- # SELECT ... FROM 第一張表 JOIN 第二張表 ON 第一和第二張表的連線條件 JOIN 第三張表 ON 前面的表和第三種表的連線條件 JOIN....ON...類推
- # sql99的左外連線寫法:
- SELECT e.name AS "名字",ed.city AS "城市" FROM employees_detailed ed LEFT JOIN employees e
- ON ed.location_id = e.location_id;-- ed的location_id範圍比e更大,而ed在左表,故是左外連線
- # sql99的右外連線寫法:
- SELECT e.name AS "名字",ed.city AS "城市" FROM employees e RIGHT JOIN employees_detailed ed
- ON ed.location_id = e.location_id;-- ed的location_id範圍比e更大,而ed在右表,故是右外連線
- # SELECT ... FROM 左表 LEFT /RIGHT JOIN 右表 ON 連線條件..
- # 看左表和右表的所對應的連線條件,那個連線條件更“大”,就是哪邊連線。
- # sql99的滿外連線寫法:(滿外連線在mysql中不支援)
- # SELECT e.name AS "名字",ed.city AS "城市" FROM employees e FULL OUTER JOIN employees_detailed ed
- # ON ed.location_id = e.location_id; 報錯,mysql不支援該寫法,但是這是正確的寫法
- # 用UNION和UNION ALL合併查詢結果
- # UNION操作符:返回兩個查詢的結果集的並集,去除重複記錄,類似集合
- # UNION ALL操作符:返回兩個查詢的結果集的並集,對於兩個結果集的重複部分,不去重!類似集合
- # 注意:能用UNION ALL時就不要用UNION,提高資料查詢效率,因為UNION是在UNION ALL的基礎上去重,
- # 7種join的實現:
- # 有集合a(左)和集合b(右),這兩個集合有交集,集合a和集合b的交集是c
- # 求集合c:內連線
- SELECT e.department_id,e.name,e.location_id,ed.city,ed.position FROM employees e JOIN employees_detailed ed
- ON e.location_id = ed.location_id;
- # 求集合a:左外連線
- SELECT e.department_id,e.name,e.location_id,ed.city,ed.position FROM employees e LEFT JOIN employees_detailed ed
- ON e.location_id = ed.location_id;
- # 求集合b:右外連線
- SELECT e.department_id,e.name,e.location_id,ed.city,ed.position FROM employees e RIGHT JOIN employees_detailed ed
- ON e.location_id = ed.location_id;
- # 求集合a-c的部分:看要求來寫,用where過濾
- SELECT e.department_id,e.name,e.location_id,ed.city,ed.position FROM employees e JOIN employees_detailed ed
- ON e.location_id = ed.location_id WHERE e.location_id > 10 OR e.location_id < 0;
- # 求集合b-c的部分和上面的類似
- # 用UNION ALL求滿外連線(a和b的並集,取掉重複的部分!):用集合a+去掉重複部分的集合b 或 集合b+去掉重複部分的集合a
- SELECT e.department_id,e.name,e.location_id,ed.city,ed.position FROM employees e RIGHT JOIN employees_detailed ed
- ON e.location_id = ed.location_id
- UNION ALL-- 改成UNION沒有重複的了。。。
- SELECT e.department_id,e.name,e.location_id,ed.city,ed.position FROM employees e JOIN employees_detailed ed
- ON e.location_id = ed.location_id WHERE e.location_id > 10 OR e.location_id < 0;-- 這個好像有重複的。。。反正意思和這個差不多
- # sql99的新特性:自然連線和using連線(擴充套件)
- # 自然連線:我們可以把自然連線理解為sql92中的等值連線,它會幫你自動查詢兩張連線表中所有相同的列名,然後進行等值連線
- SELECT * FROM employees e NATURAL JOIN employees_detailed ed; -- 雖然間接,但不夠靈活
- # USING連線:using裡面放連線條件 USING(共有的連線條件);
- SELECT * FROM employees e JOIN employees_detailed ed USING(location_id);