1. 程式人生 > 其它 >MYSQL--第三和第四章筆記

MYSQL--第三和第四章筆記

  • # 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);