MySQL數(shù)據(jù)庫學(xué)習(xí)之去重與連接查詢詳解
1.去重
有些 MySQL 數(shù)據(jù)表中可能存在重復(fù)的記錄,有些情況我們允許重復(fù)數(shù)據(jù)的存在,但有時候我們也需要刪除這些重復(fù)的數(shù)據(jù)。
例如:去重顯示崗位信息:
mysql> select distinct job from emp; +-----------+ | job | +-----------+ | CLERK | | SALESMAN | | MANAGER | | ANALYST | | PRESIDENT | +-----------+ 5 rows in set (0.02 sec)
另一個示例:聯(lián)合去重,查找部門和崗位的獨有信息:
mysql> select distinct job,deptno from emp; +-----------+--------+ | job | deptno | +-----------+--------+ | CLERK | 20 | | SALESMAN | 30 | | MANAGER | 20 | | MANAGER | 30 | | MANAGER | 10 | | ANALYST | 20 | | PRESIDENT | 10 | | CLERK | 30 | | CLERK | 10 | +-----------+--------+ 9 rows in set (0.00 sec)
另一個示例:現(xiàn)在我們想統(tǒng)計一下工作崗位的數(shù)量,結(jié)合使用count函數(shù):
mysql> select count(distinct job) from emp; +---------------------+ | count(distinct job) | +---------------------+ | 5 | +---------------------+ 1 row in set (0.00 sec)
2.連接查詢
我們已經(jīng)學(xué)會了如何在一張表中讀取數(shù)據(jù),這是相對簡單的,但是在真正的應(yīng)用中經(jīng)常需要從多個數(shù)據(jù)表中讀取數(shù)據(jù)。
JOIN 按照功能大致分為如下三類:
INNER JOIN(內(nèi)連接,或等值連接):獲取兩個表中字段匹配關(guān)系的記錄。
LEFT JOIN(左連接):獲取左表所有記錄,即使右表沒有對應(yīng)匹配的記錄。
RIGHT JOIN(右連接): 與 LEFT JOIN 相反,用于獲取右表所有記錄,即使左表沒有對應(yīng)匹配的記錄。
多表連接的機制是:從其中一個表中取出每一條數(shù)據(jù),從另一個表中的數(shù)據(jù)行進行匹配。這就涉及到了效率控制問題
使用where進行多表連接查詢
現(xiàn)在我們來演示一個例子:取出每個員工的名字和部門名字:
mysql> select ename,dname -> from emp,dept -> where emp.deptno = dept.deptno; +--------+------------+ | ename | dname | +--------+------------+ | SMITH | RESEARCH | | ALLEN | SALES | | WARD | SALES | | JONES | RESEARCH | | MARTIN | SALES | | BLAKE | SALES | | CLARK | ACCOUNTING | | SCOTT | RESEARCH | | KING | ACCOUNTING | | TURNER | SALES | | ADAMS | RESEARCH | | JAMES | SALES | | FORD | RESEARCH | | MILLER | ACCOUNTING | +--------+------------+ 14 rows in set (0.00 sec)
上面的sql語句實際上效率很低,我們嘗試進行優(yōu)化(給表起別名):(sql92語法)
mysql> select e.ename,d.dname -> from emp e,dept d -> where e.deptno = d.deptno; +--------+------------+ | ename | dname | +--------+------------+ | SMITH | RESEARCH | | ALLEN | SALES | | WARD | SALES | | JONES | RESEARCH | | MARTIN | SALES | | BLAKE | SALES | | CLARK | ACCOUNTING | | SCOTT | RESEARCH | | KING | ACCOUNTING | | TURNER | SALES | | ADAMS | RESEARCH | | JAMES | SALES | | FORD | RESEARCH | | MILLER | ACCOUNTING | +--------+------------+ 14 rows in set (0.00 sec)
注意:表的連接次數(shù)越多,效率越低,請盡量減少表的連接次數(shù)!
內(nèi)連接 - 等值連接
還是上面的例子,取出每個員工的名字和部門名字:(sql99語法)
內(nèi)連接,我們使用inner
mysql> select e.ename,d.dname -> from emp e -> inner join -> dept d -> on -> e.deptno = d.deptno; +--------+------------+ | ename | dname | +--------+------------+ | SMITH | RESEARCH | | ALLEN | SALES | | WARD | SALES | | JONES | RESEARCH | | MARTIN | SALES | | BLAKE | SALES | | CLARK | ACCOUNTING | | SCOTT | RESEARCH | | KING | ACCOUNTING | | TURNER | SALES | | ADAMS | RESEARCH | | JAMES | SALES | | FORD | RESEARCH | | MILLER | ACCOUNTING | +--------+------------+ 14 rows in set (0.00 sec)
sql99的優(yōu)點是:表的連接是獨立的,不占用where的位置。使sql語句整體更加清晰
內(nèi)連接 - 非等值連接
案例:找出每個員工的薪資等級,要求顯示員工名,薪資,薪資等級
mysql> select -> e.ename,e.sal,s.grade -> from -> emp e -> inner join -> salgrade s -> on -> e.sal between s.losal and s.hisal; +--------+---------+-------+ | ename | sal | grade | +--------+---------+-------+ | SMITH | 800.00 | 1 | | ALLEN | 1600.00 | 3 | | WARD | 1250.00 | 2 | | JONES | 2975.00 | 4 | | MARTIN | 1250.00 | 2 | | BLAKE | 2850.00 | 4 | | CLARK | 2450.00 | 4 | | SCOTT | 3000.00 | 4 | | KING | 5000.00 | 5 | | TURNER | 1500.00 | 3 | | ADAMS | 1100.00 | 1 | | JAMES | 950.00 | 1 | | FORD | 3000.00 | 4 | | MILLER | 1300.00 | 2 | +--------+---------+-------+ 14 rows in set (0.01 sec)
內(nèi)連接 - 自連接
案例:查詢員工的上級領(lǐng)導(dǎo),要求顯示員工名和對應(yīng)的領(lǐng)導(dǎo)名
我們可以發(fā)現(xiàn),員工和領(lǐng)導(dǎo)的關(guān)系在一張表中,此時需要用到自連接(技巧:一張表看成兩張表)
mysql> select -> a.ename as '員工名',b.ename as '領(lǐng)導(dǎo)名' -> from emp a -> join emp b -> on -> a.mgr = b.empno; +-----------+-----------+ | 員工名 | 領(lǐng)導(dǎo)名 | +-----------+-----------+ | SMITH | FORD | | ALLEN | BLAKE | | WARD | BLAKE | | JONES | KING | | MARTIN | BLAKE | | BLAKE | KING | | CLARK | KING | | SCOTT | JONES | | TURNER | BLAKE | | ADAMS | SCOTT | | JAMES | BLAKE | | FORD | JONES | | MILLER | CLARK | +-----------+-----------+ 13 rows in set (0.00 sec)
外連接 - 左右外連接
外連接與內(nèi)連接的區(qū)別是,外連接沒有匹配成功的某一個表的記錄也會被取出
案例:查找員工的部門信息。要求部門即使沒有員工也要查出
mysql> select -> e.ename,d.dname -> from emp e -> right join dept d -> on -> e.deptno = d.deptno; +--------+------------+ | ename | dname | +--------+------------+ | SMITH | RESEARCH | | ALLEN | SALES | | WARD | SALES | | JONES | RESEARCH | | MARTIN | SALES | | BLAKE | SALES | | CLARK | ACCOUNTING | | SCOTT | RESEARCH | | KING | ACCOUNTING | | TURNER | SALES | | ADAMS | RESEARCH | | JAMES | SALES | | FORD | RESEARCH | | MILLER | ACCOUNTING | | NULL | OPERATIONS | +--------+------------+ 15 rows in set (0.00 sec)
同樣的,如果是左外連接,將查詢出左表的全部數(shù)據(jù),使用left join關(guān)鍵字即可
外連接的查詢結(jié)果條數(shù)一定是 >= 內(nèi)連接的查詢結(jié)果條數(shù)
三表連接
更為復(fù)雜的情況是,群表連接
我們來看一個案例:
找出每個員工的部門名稱及工資等級。要求顯示員工名,部門名,薪資,薪資等級
mysql> select -> e.ename,e.sal,d.dname,s.grade -> from emp e -> join dept d -> on e.deptno = d.deptno -> join salgrade s -> on e.sal between s.losal and s.hisal; +--------+---------+------------+-------+ | ename | sal | dname | grade | +--------+---------+------------+-------+ | SMITH | 800.00 | RESEARCH | 1 | | ALLEN | 1600.00 | SALES | 3 | | WARD | 1250.00 | SALES | 2 | | JONES | 2975.00 | RESEARCH | 4 | | MARTIN | 1250.00 | SALES | 2 | | BLAKE | 2850.00 | SALES | 4 | | CLARK | 2450.00 | ACCOUNTING | 4 | | SCOTT | 3000.00 | RESEARCH | 4 | | KING | 5000.00 | ACCOUNTING | 5 | | TURNER | 1500.00 | SALES | 3 | | ADAMS | 1100.00 | RESEARCH | 1 | | JAMES | 950.00 | SALES | 1 | | FORD | 3000.00 | RESEARCH | 4 | | MILLER | 1300.00 | ACCOUNTING | 2 | +--------+---------+------------+-------+ 14 rows in set (0.00 sec)
再來看一個更復(fù)雜的情況:
找出每個員工的部門名稱及工資等級及領(lǐng)導(dǎo)名稱。要求顯示員工名,部門名,領(lǐng)導(dǎo)名,薪資,薪資等級
mysql> select -> e.ename,e.sal,d.dname,s.grade,l.ename -> from emp e -> join dept d -> on e.deptno = d.deptno -> join salgrade s -> on e.sal between s.losal and s.hisal -> left join -> emp l -> on e.mgr = l.empno; +--------+---------+------------+-------+-------+ | ename | sal | dname | grade | ename | +--------+---------+------------+-------+-------+ | SMITH | 800.00 | RESEARCH | 1 | FORD | | ALLEN | 1600.00 | SALES | 3 | BLAKE | | WARD | 1250.00 | SALES | 2 | BLAKE | | JONES | 2975.00 | RESEARCH | 4 | KING | | MARTIN | 1250.00 | SALES | 2 | BLAKE | | BLAKE | 2850.00 | SALES | 4 | KING | | CLARK | 2450.00 | ACCOUNTING | 4 | KING | | SCOTT | 3000.00 | RESEARCH | 4 | JONES | | KING | 5000.00 | ACCOUNTING | 5 | NULL | | TURNER | 1500.00 | SALES | 3 | BLAKE | | ADAMS | 1100.00 | RESEARCH | 1 | SCOTT | | JAMES | 950.00 | SALES | 1 | BLAKE | | FORD | 3000.00 | RESEARCH | 4 | JONES | | MILLER | 1300.00 | ACCOUNTING | 2 | CLARK | +--------+---------+------------+-------+-------+ 14 rows in set (0.00 sec)
以上就是MySQL數(shù)據(jù)庫學(xué)習(xí)之去重與連接查詢詳解的詳細內(nèi)容,更多關(guān)于MySQL去重 連接查詢的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MySQL學(xué)習(xí)之InnoDB結(jié)構(gòu)探秘
這篇文章主要是對InnoDB結(jié)構(gòu)的探秘,InnoDB是基于磁盤存儲,其存儲的最基本單元是頁,大小為16KB。而CPU和磁盤之間速度相差懸殊,所以通常使用內(nèi)存中的緩沖池來提高性能,感興趣的同學(xué)可以參考閱讀2023-03-03MySQL啟動報錯問題InnoDB:Unable to lock/ibdata1 error
這篇文章主要介紹了MySQL啟動報錯問題InnoDB:Unable to lock/ibdata1 error,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-07-07mysql not in、left join、IS NULL、NOT EXISTS 效率問題記錄
mysql not in、left join、IS NULL、NOT EXISTS 效率問題記錄,需要的朋友可以參考下。2011-12-12