取平均值:avgmysql
mysql> select avg(sal) from emp; +-------------+ | avg(sal) | +-------------+ | 2073.214286 | +-------------+ 1 row in set (0.60 sec)
最大值:maxweb
取記錄數:count sql
mysql> select count(sal) from emp; +------------+ | count(sal) | +------------+ | 14 | +------------+ 1 row in set (0.04 sec)
mysql> select distinct job from emp;svg
+-----------+ | job | +-----------+ | CLERK | | SALESMAN | | MANAGER | | ANALYST | | PRESIDENT | +-----------+ 5 rows in set (0.09 sec)
統計公司一共有幾個工做崗位函數
mysql> select count(distinct job) from emp; +---------------------+ | count(distinct job) | +---------------------+ | 5 | +---------------------+ 1 row in set (0.00 sec)
經過哪一個或者哪些字段進行分組code
若一條DQL語句中有group by子句,那麼select關鍵字後面只能跟參與分組的字段和分組函數(好比ename這些是不能夠的,不是分組字段)router
一、找出每一個工做崗位的最高薪水xml
分析:先按照工做崗位分組,再使用max求每組最高記錄排序
mysql> select job,max(sal) from emp group by job; +-----------+----------+ | job | max(sal) | +-----------+----------+ | ANALYST | 3000.00 | | CLERK | 1300.00 | | MANAGER | 2975.00 | | PRESIDENT | 5000.00 | | SALESMAN | 1600.00 | +-----------+----------+ 5 rows in set (0.00 sec)
二、計算每一個部門的平均薪水ip
mysql> select -> deptno,avg(sal) as avgsal -> from -> emp -> group by -> deptno; +--------+-------------+ | deptno | avgsal | +--------+-------------+ | 10 | 2916.666667 | | 20 | 2175.000000 | | 30 | 1566.666667 | +--------+-------------+ 3 rows in set (0.00 sec)
三、計算不一樣工做崗位的最高薪水
mysql> select -> deptno,job,avg(sal) as avgsal -> from -> emp -> group by -> deptno,job; +--------+-----------+-------------+ | deptno | job | avgsal | +--------+-----------+-------------+ | 10 | CLERK | 1300.000000 | | 10 | MANAGER | 2450.000000 | | 10 | PRESIDENT | 5000.000000 | | 20 | ANALYST | 3000.000000 | | 20 | CLERK | 950.000000 | | 20 | MANAGER | 2975.000000 | | 30 | CLERK | 950.000000 | | 30 | MANAGER | 2850.000000 | | 30 | SALESMAN | 1400.000000 | +--------+-----------+-------------+ 9 rows in set (0.04 sec)
找出每一個工做崗位的最高薪水,除manager以外
mysql> select -> job,avg(sal) -> from -> emp -> group by -> job -> having -> avg(sal)>1500; +-----------+-------------+ | job | avg(sal) | +-----------+-------------+ | ANALYST | 3000.000000 | | MANAGER | 2758.333333 | | PRESIDENT | 5000.000000 | +-----------+-------------+ 3 rows in set (0.09 sec)
注意上面爲何不能用where,由於where關鍵字後面不能用分組函數,分組函數必須在分組完成後執行,而分組要group by。而group by在where後執行
通常狀況儘可能在where中過濾,實在沒法過濾的數據,一般是須要先分組以後再過濾,此時能夠選擇having,這牽扯到效率問題
select ... from 從某張表中檢索數據 ... where 通過某條件進行過濾 ... group by 分組 ... having 分組以後不滿意再過濾 ... order by 排序輸出 ...
以上關鍵字順序不能改變,嚴格遵照
如下是執行順序
一、from
二、where
三、group by
四、having
五、select
六、order by
外鏈接的查詢結果都是一直大於等於內鏈接的查詢結果
會發生總記錄是兩張表記錄乘積(此現象是笛卡爾積現象,爲了不該現象發生,必須在錶鏈接時候加上限制)
一、內鏈接(等值鏈接)—————查詢每一個員工所在的部門名稱,要求最終顯示員工名和對應的部門名(兩張表:員工表(部門號)、部門表(部門號))
SQL92語法:(屬於內鏈接中的等值鏈接)(缺點:錶鏈接與過濾同時了,結構不清晰)
mysql> select -> e.ename,d.dname -> from -> emp e,dept d -> where -> e.deptno=d.deptno; +--------+------------+ | ename | dname | +--------+------------+ | CLARK | ACCOUNTING | | KING | ACCOUNTING | | MILLER | ACCOUNTING | | SMITH | RESEARCH | | JONES | RESEARCH | | SCOTT | RESEARCH | | ADAMS | RESEARCH | | FORD | RESEARCH | | ALLEN | SALES | | WARD | SALES | | MARTIN | SALES | | BLAKE | SALES | | TURNER | SALES | | JAMES | SALES | +--------+------------+ 14 rows in set (0.15 sec)
SQL99語法(inner能夠省略)(好處:錶鏈接與過濾分離,在最後加where便可過濾,結構清晰)
mysql> select -> e.ename,d.dname -> from -> emp e -> inner join -> dept d -> on -> e.deptno=d.deptno; +--------+------------+ | ename | dname | +--------+------------+ | CLARK | ACCOUNTING | | KING | ACCOUNTING | | MILLER | ACCOUNTING | | SMITH | RESEARCH | | JONES | RESEARCH | | SCOTT | RESEARCH | | ADAMS | RESEARCH | | FORD | RESEARCH | | ALLEN | SALES | | WARD | SALES | | MARTIN | SALES | | BLAKE | SALES | | TURNER | SALES | | JAMES | SALES | +--------+------------+ 14 rows in set (0.00 sec)
二、內鏈接(非等值鏈接,SQL99)————找出每個員工對應的工資等級,要求顯示員工名,工資,工資等級(兩張表:員工表,工資等級表(salgrade))
mysql> select -> e.ename,e.sal,s.grade -> from -> emp e -> 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.03 sec)
三、內鏈接(自鏈接,SQL99)——找出每一個員工的上級領導,要求顯示員工名以及對應的領導名(一張表當作兩張表)
如下是員工表,表中也有員工序號和對應上級的序號,便可看出兩張表
mysql> select * from emp; +-------+--------+-----------+------+------------+---------+---------+-------- | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO +-------+--------+-----------+------+------------+---------+---------+-------- | 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 | 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 | 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 | 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 | 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 | 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 | 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 | 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 | 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 | 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 +-------+--------+-----------+------+------------+---------+---------+-------- 14 rows in set (0.00 sec) mysql> select -> a.ename as empname,b.ename as leadername -> from -> emp a -> join -> emp b -> on -> a.mgr=b.empno; +---------+------------+ | empname | leadername | +---------+------------+ | 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)
SQL92語法就是將join改爲’,’,on改爲where
四、外鏈接(右鏈接)——找出每一個員工對應的部門名稱,要求部門名稱所有顯示(部分多出來的記錄將用null與其匹配)(左鏈接的話將dept和emp換個位置就好)
mysql> select -> e.ename,d.dname -> from -> emp e -> right outer join -> dept d -> on -> e.deptno=d.deptno; +--------+------------+ | ename | dname | +--------+------------+ | CLARK | ACCOUNTING | | KING | ACCOUNTING | | MILLER | ACCOUNTING | | SMITH | RESEARCH | | JONES | RESEARCH | | SCOTT | RESEARCH | | ADAMS | RESEARCH | | FORD | RESEARCH | | ALLEN | SALES | | WARD | SALES | | MARTIN | SALES | | BLAKE | SALES | | TURNER | SALES | | JAMES | SALES | | NULL | OPERATIONS | +--------+------------+ 15 rows in set (0.05 sec)
五、找出每一個員工對應的領導名,要求顯示全部的員工
mysql> select a.ename empname,b.ename leadername from emp a join emp b on a.mgr= b.empno; +---------+------------+ | empname | leadername | +---------+------------+ | 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)
(多張表)六、找出每一個員工對應的部門名稱,以及該員工對應的部門名稱,工資等級。要求顯示員工名、部門名、工資等級
多張表進行錶鏈接的語法格式(a,b,c表)
原理:a與b鏈接後,再a與c鏈接
select ... from a join b on 條件 join c on 條件; mysql> select e.ename,d.dname,s.grade from emp e join dept d on e.deptno=d.deptn o join salgrade s on e.sal between s.losal and s.hisal; +--------+------------+-------+ | ename | dname | grade | +--------+------------+-------+ | SMITH | RESEARCH | 1 | | ALLEN | SALES | 3 | | WARD | SALES | 2 | | JONES | RESEARCH | 4 | | MARTIN | SALES | 2 | | BLAKE | SALES | 4 | | CLARK | ACCOUNTING | 4 | | SCOTT | RESEARCH | 4 | | KING | ACCOUNTING | 5 | | TURNER | SALES | 3 | | ADAMS | RESEARCH | 1 | | JAMES | SALES | 1 | | FORD | RESEARCH | 4 | | MILLER | ACCOUNTING | 2 | +--------+------------+-------+ 14 rows in set (0.05 sec)
由於區份內鏈接和外鏈接依靠的不是這些關鍵字,而是看SQL語句中是否存在left/right,若存在,標識必定是個外鏈接,其餘都是內鏈接
加強可讀性
子查詢就是嵌套的select語句(select語句嵌套select語句)
找出薪水比公司平均薪水高的員工,要求顯示員工名和薪水
第一步找出公司的平均水平
select avg(sal) from emp;
第二步找出薪水大於平均薪水的員工信息
mysql> select ename,sal from emp where sal>(select avg(sal) from emp); +-------+---------+ | ename | sal | +-------+---------+ | JONES | 2975.00 | | BLAKE | 2850.00 | | CLARK | 2450.00 | | SCOTT | 3000.00 | | KING | 5000.00 | | FORD | 3000.00 | +-------+---------+ 6 rows in set (0.00 sec)
找出每一個部門的平均薪水,並找出平均薪水的薪水等級
第一步找出每一個部門的平均薪水
mysql> select avg(sal) as avgsal from emp group by deptno;
第二步將上面的查詢結果當作臨時表t,t表和salgrade s表進行錶鏈接,條件:t.avgsal between s.losal and s.hisal
mysql> select -> t.deptno,t.avgsal,s.grade -> from -> (select deptno,avg(sal) as avgsal from emp group by deptno) t -> join -> salgrade s -> on -> t.avgsal -> between -> s.losal -> and -> s.hisal; +--------+-------------+-------+ | deptno | avgsal | grade | +--------+-------------+-------+ | 30 | 1566.666667 | 3 | | 10 | 2916.666667 | 4 | | 20 | 2175.000000 | 4 | +--------+-------------+-------+ 3 rows in set (0.12 sec)
顯示員工名與其對應的部門名
mysql> select e.ename,(select d.dname from dept d where e.deptno=d.deptno) as dn ame from emp e; +--------+------------+ | 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)