实战案例:https://help.aliyun.com/document_detail/51009.html?spm=a2c4g.11186623.2.20.4e6b1ad7ljabib
一、创建数据库与表
和原链接中一致,将string替换成MySQL中的varchar(256)
二、导入数据
使用本地MySQL导入txt文本:
mysqlimport -u root -p --local --fields-terminated-by="," aliyun_test1 emp.txt
其中,aliyun_test1代表数据库名称,emp.txt代表了数据文件的路径为cmd当前目录下的txt文件,也代表了table名称为emp。若没事先建表则会报错,说表 aliyun_test1.emp不存在。
具体mysqlimport命令的使用教程:https://www.runoob.com/mysql/mysql-database-import.html
-
示例一:列出员工人数大于零的所有部门。
为了避免数据量太大,您需要使用Join进行改写。
select a.deptno,a.dname,a.loc,b.num from
dept a join
(select deptno, count(*) as num from emp group by deptno) b
on a.deptno = b.deptno;
这里在子查询中使用了count函数,故可显示人员数目。这里用了inner join,保证了emp表中未出现的deptno不会出现在结果中。若使用left join,则结果中还会保留。
或官方解法,其实是使用join改写了where in的写法,效率更高:
SELECT d.*
FROM dept d
JOIN (
SELECT DISTINCT deptno AS no
FROM emp
) e
ON d.deptno = e.no;
或where in写法,效率比join低,但是好写(不推荐):
SELECT d.*
FROM dept d
where deptno in(
SELECT DISTINCT deptno
FROM emp
) ;
- 示例二:列出薪金比SMITH多的所有员工。
select * from emp where sal > (select sal from emp where ename='SMITH');
官方解法,MapJoin(https://help.aliyun.com/document_detail/73785.html)的典型场景。:
SELECT /*+ MapJoin(a) */ e.empno
, e.ename
, e.sal
FROM emp e
JOIN (
SELECT MAX(sal) AS sal
FROM `emp`
WHERE `ENAME` = 'SMITH'
) a
ON e.sal > a.sal;
高效之处:使用了ODPS的mapjoin注释,能有效提高小表的执行速度,此处小表为Smith的sal值,其实就一个值罢了。同时使用join代替了where比较语句,提高了执行效率。
-
示例三:列出所有员工的姓名及其直接上级的姓名。
非等值连接。
select a.empno,a.ename, b.ename as manager
from emp a left join emp b
on a.mgr = b.empno;
这里用left join,因为老板KING没上级,若用inner join则不会显示KING。
- 示例四:列出最低薪金大于1500的所有工作。
select job, min(sal) as sal
from emp
group by job
having sal > 1500;
这里得用having,在group by后做过滤,若用where则是之前过滤。
-
示例五:列出在每个部门工作的员工数量、平均工资
平均则要用聚合函数。
SELECT COUNT(empno) AS cnt_emp
, ROUND(AVG(sal), 2) AS avg_sal
FROM emp
GROUP BY DEPTNO;
- 示例七: 用一个SQL写出每个部门的人数、CLERK(办事员)的人数占该部门总人数占比。
select deptno, count(*) as num,
round( sum(case when
job='CLERK' then 1 else 0 end)
/ count(*) ,2)
as clerk_rate from emp group by deptno;
网友评论