MySQL多表數據記載查詢詳解。本站提示廣大學習愛好者:(MySQL多表數據記載查詢詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL多表數據記載查詢詳解正文
在現實運用中,常常須要完成在一個查詢語句中顯示多張表的數據,這就是所謂的多表數據記載銜接查詢,簡稱來年將诶查詢。
在詳細完成銜接查詢操作時,起首將兩個或兩個以上的表依照某個前提銜接起來,然後再查詢到所請求的數據記載。銜接查詢分為內銜接查詢和外銜接查詢。
在詳細運用中,假如須要完成多表數據記載查詢,普通不應用銜接查詢,由於該操作效力比擬低。因而MySQL又供給 了銜接查詢的替換操作,子查詢操作。
1.關系數據操作:
在銜接查詢中,起首須要對兩張或兩張以上的表停止銜接操作。銜接操作是關系數據操作中專門用於數據操作的關系運算。
1.1 並(UNION):
在SQL說話中存在一種關系數據操作,叫做並操作。“並”就是把具有雷同字段數量和字段類型的表歸並到一路。經由過程並操作將兩張表的數據記載歸並到一路,歸並後的字段數為 表1的字段數或許表2的字段數;歸並後的總記載數為:表1的記載數 + 表2的記載數 - 表1和表2 反復的記載數。
1.2 笛卡爾積(CARTESIAN PRODUCT):
在SQL說話中存在一種關系數據操作,叫做笛卡爾積操作。笛卡爾就是沒有銜接前提,表中的數據隨意率性的組合。笛卡爾積的字段數為 表1的字段數 + 表2的字段數。笛卡爾積的記載數為:表1的記載數 * 表2的記載數。
1.3 內銜接(INNER JOIN):
為了便於操作,專門供給了一種針對數據庫操作的運算—銜接(JOIN)。所謂銜接就是在表關系的笛卡爾積數據記載中,依照響應字段值的比擬前提停止選擇生成一個新的關系。銜接又分為內銜接(INNER JOIN)、外銜接(OUTER JOIN)、穿插銜接(CROSS JOIN)。
所謂內銜接,就是在表關系的笛卡爾積數據中,保存表關系中一切婚配的數據記載,捨棄不婚配的數據記載。依照婚配的前提可以分紅天然銜接、等值銜接和不等銜接。
1.3.1 天然銜接(NATURAL JOIN):
天然銜接就是在表關系的笛卡爾積中,起首依據表關系中雷同稱號的字段主動停止記載婚配,然後去失落反復的字段。
經由過程天然銜接後,新關系的字段數為:表1字段數 + 表2字段數 - 表1和表2中的反復字段數。天然銜接後新關系的記載數為:表1的記載數 * 表2的記載數 - 表1和表2雷同字段的值不相等記載數。
天然銜接又以下特色:
1. 在詳細履行天然銜接時,會主動斷定雷同稱號的字段,然落後行數據值的婚配。
2. 在履行完天然銜接的新關系中,固然可以指定包括哪些字段,然則不克不及指定履行進程中的婚配前提,即哪些字段的值停止婚配。
3. 在履行天然銜接的新關系中,履行進程中所婚配的字段名只要一個,即會去失落反復字段。
1.3.2 等值銜接:
所謂等值銜接操作就是表關系的笛卡爾積中,選擇所婚配字段值相等的數據記載。
經由過程等值銜接後,新關系的字段數為:表1字段數 + 表2字段數。等值銜接後新關系的記載數為:表1的記載數 * 表2的記載數 - 表1和表2雷同字段的值不相等記載數。
與天然銜接比擬,等值銜接操作須要在履行進程頂用“=”指定婚配前提,在新關系中不會去失落反復字段。
1.3.3 不等銜接:
所謂不等銜接操作就是表關系的笛卡爾積中,選擇所婚配字段值不相等的數據記載。
經由過程不等銜接後,新關系的字段數為:表1字段數 + 表2字段數。等值銜接後新關系的記載數為:表1的記載數 * 表2的記載數 - 表1和表2雷同字段的值相等的記載數。
與天然銜接比擬,等值銜接操作須要在履行進程頂用“!=”指定婚配前提,在新關系中不會去失落反復字段。
1.4 外銜接(OUTER JOIN):
所謂外銜接(OUTER JOIN),就是在表關系的笛卡爾積數據記載中,不只保存表關系中一切婚配的數據記載,並且還會保存部門不婚配的數據記載。依照保存不不婚配前提數據記載起源可以分為:左外銜接、右外銜接、全外銜接。
1.4.1 左外銜接:
所謂左外銜接操作就是表關系的笛卡爾積中,除選擇相婚配的數據記載,還包括聯系關系右邊表中不婚配的數據記載。
經由過程左外銜接後,新關系的字段數為:左表字段數 + 右表字段數。左外銜接後新關系的記載數為:左表的記載數 * 右表的記載數 - 左表和右表雷同字段的值不相等的記載數 + 左表中未婚配的記載數。
1.4.2 右外銜接:
所謂右外銜接操作就是表關系的笛卡爾積中,除選擇相婚配的數據記載,還包括聯系關系左邊表中不婚配的數據記載。
經由過程右外銜接後,新關系的字段數為:左表字段數 + 右表字段數。右外銜接後新關系的記載數為:左表的記載數 * 右表的記載數 - 左表和右表雷同字段的值不相等的記載數 + 右表中未婚配的記載數。
1.4.3 全外銜接:
所謂右外銜接操作就是表關系的笛卡爾積中,除選擇相婚配的數據記載,還包括聯系關系閣下雙方表中不婚配的數據記載。
經由過程全外銜接後,新關系的字段數為:左表字段數 + 右表字段數。全外銜接後新關系的記載數為:左表的記載數 * 右表的記載數 - 左表和右表雷同字段的值不相等的記載數 + 左表未婚配的記載數 + 右表中未婚配的記載數。
2.內銜接查詢:
在MySQL中完成銜接查詢有兩種語法:
1. 在from子句中應用逗號辨別多個表,在where子句中經由過程邏輯表達式來完成婚配前提,從而完成表的銜接。
2. ANSI銜接語法情勢,在from子句中應用“join on”症結字,而銜接前提寫在症結字on子句中。推舉應用第二種方法。
依照婚配前提,內銜接查詢可以分為兩類:等值銜接;不等銜接。
內銜接查詢語法為:
select field1, field2 ...fieldn from join_tablename1 inner join join_tablename2 [inner join join_tablename] on join_condition
//參數filedn 表現所要查詢的字段稱號,起源於所銜接的表join_tablename1 和 join_tablename2,症結字inner join表停止內銜接,join_condition表現停止婚配的前提。
2.1 自銜接:
內銜接查詢中存在一種特別的等值銜接—自銜接。所謂自銜接就是指表與其本身停止銜接。
示例(查詢每一個雇員的姓名、職位、引導姓名):
mysql> select e.ename,e.job,l.ename from t_employee e inner join t_employee l on e.MGR=l.empno; +---------+----------+-------+ | ename | job | ename | +---------+----------+-------+ | SCOTT | ANALYST | JONES | | FORD | ANALYST | JONES | | ALLEN | SALESMAN | BLAKE | | MARD | SALESMAN | BLAKE | | MARRTIN | SALESMAN | BLAKE | | TURNER | SALESMAN | BLAKE | | JAMES | CLEAR | BLAKE | | MILLER | CLEAR | CLARK | | ADAMS | CLEAR | SCOTT | | JONES | MANAGER | KING | | BLAKE | MANAGER | KING | | CLARK | MANAGER | KING | | SMITH | CLEAR | FORD | +---------+----------+-------+ 13 rows in set (0.00 sec)
2.2等值銜接:
內銜接查詢中的等值銜接,就是在症結字on後的婚配前提中經由過程等於關系運算符“=”來完成等值前提。
示例:
mysql> select e.empno,e.ename,e.job,d.dname,d.loc from t_employee e inner join t_dept d on e.deptno=d.deptno; +-------+---------+-----------+------------+----------+ | empno | ename | job | dname | loc | +-------+---------+-----------+------------+----------+ | 7788 | SCOTT | ANALYST | ACCOUNTING | NEW YORK | | 7839 | KING | PRESIDENT | ACCOUNTING | NEW YORK | | 7934 | MILLER | CLEAR | ACCOUNTING | NEW YORK | | 7369 | SMITH | CLEAR | RESEARCH | DALLAS | | 7499 | ALLEN | SALESMAN | RESEARCH | DALLAS | | 7566 | JONES | MANAGER | RESEARCH | DALLAS | | 7782 | CLARK | MANAGER | RESEARCH | DALLAS | | 7876 | ADAMS | CLEAR | RESEARCH | DALLAS | | 7902 | FORD | ANALYST | RESEARCH | DALLAS | | 7521 | MARD | SALESMAN | SALES | CHICAGO | | 7654 | MARRTIN | SALESMAN | SALES | CHICAGO | | 7698 | BLAKE | MANAGER | SALES | CHICAGO | | 7844 | TURNER | SALESMAN | SALES | CHICAGO | | 7900 | JAMES | CLEAR | SALES | CHICAGO | +-------+---------+-----------+------------+----------+ 14 rows in set (0.00 sec)
2.3不等銜接:
內銜接查詢中的不等銜接,就是在症結字on後的婚配前提中經由過程除等於關系運算符來完成不等前提外,可使用的關系運算符包括> >= < <= !=
示例:
mysql> select e.ename employeename, e.job,l.ename loadername from t_employee e inner join t_employee l on e.mgr=l.empno and e.empno>l.empno; +--------------+----------+------------+ | employeename | job | loadername | +--------------+----------+------------+ | SCOTT | ANALYST | JONES | | FORD | ANALYST | JONES | | TURNER | SALESMAN | BLAKE | | JAMES | CLEAR | BLAKE | | MILLER | CLEAR | CLARK | | ADAMS | CLEAR | SCOTT | +--------------+----------+------------+ 6 rows in set (0.00 sec)
3.外銜接查詢:
外銜接查詢會前往所操作表中至多一個表的一切數據。外銜接分為三類:左外銜接、右外銜接、全外銜接
語法為:
select field1, field2, ...fieldn from join_tablename1 left|rigth|full [outer] join join_tablename2 on join_condition
3.1左外銜接:
外銜接查詢中的左外銜接,就是指新關系中履行婚配前提時,以症結字left join 右邊的表為參考。
示例:
mysql> select e.ename employeename, e.job job,l.ename leadername from t_employee e left join t_employee l on e.mgr=l.empno; +--------------+-----------+------------+ | employeename | job | leadername | +--------------+-----------+------------+ | SMITH | CLEAR | FORD | | ALLEN | SALESMAN | BLAKE | | MARD | SALESMAN | BLAKE | | JONES | MANAGER | KING | | MARRTIN | SALESMAN | BLAKE | | BLAKE | MANAGER | KING | | CLARK | MANAGER | KING | | SCOTT | ANALYST | JONES | | KING | PRESIDENT | NULL | | TURNER | SALESMAN | BLAKE | | ADAMS | CLEAR | SCOTT | | JAMES | CLEAR | BLAKE | | FORD | ANALYST | JONES | | MILLER | CLEAR | CLARK | +--------------+-----------+------------+ 14 rows in set (0.00 sec)
3.2右外銜接:
外銜接查詢中的右外銜接,就是指新關系中履行婚配前提時,以症結字right join 左邊的表為參考。
4.歸並查詢數據記載:
在MySQL中經由過程症結字UNION來完成並操作,便可以經由過程其將多個select語句的查詢成果歸並在一路構成新的關系。
1. 症結字union的歸並操作
症結字union會把查詢成果集直接歸並在一路,同時將會去失落反復數據記載。
2. 症結字union all的歸並操作
症結字union all會把查詢成果集直接歸並在一路。
語法為:
select field1, field2, ...fieldn from tablename1 union | union all select field1, field2, ...fieldn from tablename2 union | union all select field1, field2, ...fieldn from tablename3 ......
5.子查詢:
在MySQL中固然可以經由過程銜接查詢完成多表查詢數據記載,但卻不建議應用。這是由於銜接查詢的機能很差。是以湧現了銜接查詢的替換者子查詢。推舉應用子查詢來完成多表查詢數據記載。
5.1 為何應用子查詢:
在平常開辟中,常常接觸到查詢多表數據記載操作,例如查詢部分表t_dept和雇員表t_employee表的數據記載。關於老手,直接應用select * from t_dept t,t_employee e where t.deptno=e.deptno;這條sql語句在履行時,起首會對兩個表停止笛卡爾積操作,然後在拔取相符婚配前提的數據記載。假如兩張表的數據量較年夜,則在停止笛卡爾積操作時會形成逝世機。有經歷的開辟者平日會起首用統計函數檢查操作表笛卡爾積後的數據記載數,然後再停止多表查詢。是以多表查詢普通會經由以下步調:
1. 經由過程統計函數count(1)查詢所聯系關系表笛卡爾積後的數據的記載數。然後再停止多表查詢。
2. 假如查詢到的數據記載數mysql可以接收,然後再停止多表查詢,不然就應當斟酌經由過程其他方法來完成。
假如笛卡爾積後的數據遠弘遠於mysql軟件可以接收的規模,為懂得決多表查詢,mysql供給了子查詢來完成多表查詢。
所謂子查詢,就是指在一個查詢中嵌套了其他若干查詢,即在一個select 查詢語句的where或from子句中包括另外一個select查詢語句。在查詢語句中,外層select查詢語句稱為主查詢,where子句中select查詢語句被稱為子查詢,也被稱為嵌套查詢。
經由過程子查詢可以完成多表查詢,該查詢語句中能夠包括in,any,all,exists等症結字。除此以外還能夠包括比擬運算符。實際上子查詢可以湧現在查詢語句的任何地位,但在現實開辟中,子查詢常常湧現在where或from子句中。
where子句中的子查詢,該地位處的子查詢普通前往單行單列、多行多列、單行多列數據記載。
from子句中的子查詢,該地位處的子查詢普通前往多行多列數據記載,可以看成一張暫時表。
5.2 前往成果為單行單列和單行多列子查詢:
當子查詢的前往成果為單行蛋類數據記載時,該子查詢語句普通在主查詢語句的where子句中,平日會包括比擬運算符(> < = != 等)
5.2.1 單行單列子查詢:
示例(工資比Smith高的全體雇員信息):
mysql> select * from t_employee where sal > (select sal from t_employee where ename='smith'); +-------+---------+-----------+------+------------+---------+---------+--------+ | empno | ename | job | MGR | Hiredate | sal | comm | deptno | +-------+---------+-----------+------+------------+---------+---------+--------+ | 7499 | ALLEN | SALESMAN | 7698 | 1982-03-12 | 1600.00 | 300.00 | 20 | | 7521 | MARD | SALESMAN | 7698 | 1983-03-12 | 1250.00 | 500.00 | 30 | | 7566 | JONES | MANAGER | 7839 | 1981-03-12 | 2975.00 | NULL | 20 | | 7654 | MARRTIN | SALESMAN | 7698 | 1981-03-12 | 2850.00 | 1400.00 | 30 | | 7698 | BLAKE | MANAGER | 7839 | 1981-03-12 | 2850.00 | NULL | 30 | | 7782 | CLARK | MANAGER | 7839 | 1985-03-12 | 2450.00 | NULL | 20 | | 7788 | SCOTT | ANALYST | 7566 | 1981-03-12 | 3000.00 | NULL | 10 | | 7839 | KING | PRESIDENT | NULL | 1981-03-12 | 5000.00 | NULL | 10 | | 7844 | TURNER | SALESMAN | 7698 | 1989-03-12 | 1500.00 | 0.00 | 30 | | 7876 | ADAMS | CLEAR | 7788 | 1998-03-12 | 1100.00 | NULL | 20 | | 7900 | JAMES | CLEAR | 7698 | 1987-03-12 | 950.00 | NULL | 30 | | 7902 | FORD | ANALYST | 7566 | 0000-00-00 | 3000.00 | NULL | 20 | | 7934 | MILLER | CLEAR | 7782 | 1981-03-12 | 1300.00 | NULL | 10 | +-------+---------+-----------+------+------------+---------+---------+--------+ 13 rows in set (0.00 sec)
5.2.2 單行多列子查詢:
where子句中的子查詢除是前往單行單列的數據記載外,還可所以前往多行多列的數據記載,不外這類子查詢很少湧現。
示例(工資和職位和Smith一樣的全體雇員):
mysql> select ename,job,sal from t_employee where (sal,job)=(select sal,job from t_employee where ename='smith'); +-------+-------+--------+ | ename | job | sal | +-------+-------+--------+ | SMITH | CLEAR | 800.00 | +-------+-------+--------+ 1 row in set (0.00 sec)
5.3 前往成果為多行單列子查詢:
當子查詢的前往成果為多行單列數據記載時,該子查詢語句普通會在主查詢語句的where子句中湧現,平日會包括IN ANY ALL EXISTS等症結字。
5.3.1 帶有症結字in的子查詢:
當主查詢的前提在子查詢的查詢成果中時,可以經由過程症結字in來停止斷定。相反,假如想完成主查詢的前提不在子查詢的查詢成果中時,可以經由過程症結字not in來停止斷定。
示例:
mysql> select * from t_employee where deptno in(select deptno from t_dept); +-------+---------+-----------+------+------------+---------+---------+--------+ | empno | ename | job | MGR | Hiredate | sal | comm | deptno | +-------+---------+-----------+------+------------+---------+---------+--------+ | 7369 | SMITH | CLEAR | 7902 | 1981-03-12 | 800.00 | NULL | 20 | | 7499 | ALLEN | SALESMAN | 7698 | 1982-03-12 | 1600.00 | 300.00 | 20 | | 7521 | MARD | SALESMAN | 7698 | 1983-03-12 | 1250.00 | 500.00 | 30 | | 7566 | JONES | MANAGER | 7839 | 1981-03-12 | 2975.00 | NULL | 20 | | 7654 | MARRTIN | SALESMAN | 7698 | 1981-03-12 | 2850.00 | 1400.00 | 30 | | 7698 | BLAKE | MANAGER | 7839 | 1981-03-12 | 2850.00 | NULL | 30 | | 7782 | CLARK | MANAGER | 7839 | 1985-03-12 | 2450.00 | NULL | 20 | | 7788 | SCOTT | ANALYST | 7566 | 1981-03-12 | 3000.00 | NULL | 10 | | 7839 | KING | PRESIDENT | NULL | 1981-03-12 | 5000.00 | NULL | 10 | | 7844 | TURNER | SALESMAN | 7698 | 1989-03-12 | 1500.00 | 0.00 | 30 | | 7876 | ADAMS | CLEAR | 7788 | 1998-03-12 | 1100.00 | NULL | 20 | | 7900 | JAMES | CLEAR | 7698 | 1987-03-12 | 950.00 | NULL | 30 | | 7902 | FORD | ANALYST | 7566 | 0000-00-00 | 3000.00 | NULL | 20 | | 7934 | MILLER | CLEAR | 7782 | 1981-03-12 | 1300.00 | NULL | 10 | +-------+---------+-----------+------+------------+---------+---------+--------+ 14 rows in set (0.00 sec)
5.3.2 帶有症結字any的子查詢:
症結字any:主查詢的前提為知足子查詢的查詢成果中隨意率性一條數據記載,該症結字有三種婚配方法;
1. =any:其功效與症結字in一樣
2. > any(>=any):只需年夜於(年夜於等於)子查詢中最小的一個便可。
3. < any(<=any):只需小於(小於等於)子查詢中最年夜的一個便可。
示例(查詢雇員工資不低於職位為manager的工資):
mysql> select ename,sal from t_employee where sal>any(select sal from t_employee where job='manager'); +---------+---------+ | ename | sal | +---------+---------+ | JONES | 2975.00 | | MARRTIN | 2850.00 | | BLAKE | 2850.00 | | SCOTT | 3000.00 | | KING | 5000.00 | | FORD | 3000.00 | +---------+---------+ 6 rows in set (0.00 sec)
5.3.3 帶有症結字all的子查詢:
症結字all用來表現主查詢的前提為知足子查詢前往查詢成果中一切數據記載,有兩種婚配方法:
1. > all(>=all):比子查詢成果中最年夜的還要年夜(年夜於等於)的數據記載;
2. < all(<= all):比子查詢成果中最小的還要小(小於等於)的數據記載。
示例:
mysql> select ename,sal from t_employee where sal>all(select sal from t_employee where job='manager'); +-------+---------+ | ename | sal | +-------+---------+ | SCOTT | 3000.00 | | KING | 5000.00 | | FORD | 3000.00 | +-------+---------+ 3 rows in set (0.00 sec)
5.3.4 帶有症結字exists的子查詢:
症結字exists是一個boolean類型,當能前往成果集時為true,不克不及前往成果集時為false。查詢時exists對表面采取遍歷方法逐條查詢,每次查詢都邑比擬exists的前提語句,當exists裡的前提語句前往記載行時則前提為真,此時前往以後遍歷到的記載;反之,假如exists裡前提語句不克不及前往記載行,則拋棄以後遍歷到的記載。
5.4 前往成果為多行多列子查詢:
當子查詢的前往成果為多行多列數據記載時,該子查詢語句普通會在主查詢語句的from子句裡,被看成一張暫時表的方法來處置。
示例(查詢雇員表中各部分的部分號、部分稱號、部分地址、雇員人數、戰爭均工資):
經由過程內銜接來完成:
mysql> select d.deptno,d.dname,d.loc,count(e.empno) number,avg(e.sal) average from t_employee e inner join t_dept d on e .deptno=d.deptno group by d.deptno; +--------+------------+----------+--------+-------------+ | deptno | dname | loc | number | average | +--------+------------+----------+--------+-------------+ | 10 | ACCOUNTING | NEW YORK | 3 | 3100.000000 | | 20 | RESEARCH | DALLAS | 6 | 1987.500000 | | 30 | SALES | CHICAGO | 5 | 1880.000000 | +--------+------------+----------+--------+-------------+ 3 rows in set (0.00 sec)
經由過程子查詢來完成:
mysql> select d.deptno,d.dname,d.loc,number,average from t_dept d inner join(select deptno dno,count(empno) number,avg(s al) average from t_employee group by deptno) employee on d.deptno=employee.dno; +--------+------------+----------+--------+-------------+ | deptno | dname | loc | number | average | +--------+------------+----------+--------+-------------+ | 10 | ACCOUNTING | NEW YORK | 3 | 3100.000000 | | 20 | RESEARCH | DALLAS | 6 | 1987.500000 | | 30 | SALES | CHICAGO | 5 | 1880.000000 | +--------+------------+----------+--------+-------------+ 3 rows in set (0.00 sec)
以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。