© 康大校(herry)
这里选择大家比较熟悉的Emp/Dept表做为数据集。为方便大家操作,特提供相关的 MaxCompute建表语句和数据文件(emp表数据文件,dept表数据文件),您可自行在MaxCompute项目上创建表并上传数据。
创建emp表的DDL语句,如下所示:
试用
CREATE TABLE IF NOT EXISTS emp (
EMPNO string ,
ENAME string ,
JOB string ,
MGR bigint ,
HIREDATE datetime ,
SAL double ,
COMM double ,
DEPTNO bigint );
创建 dept 表的 DDL 语句,如下所示:
试用
CREATE TABLE IF NOT EXISTS dept (
DEPTNO bigint ,
DNAME string ,
LOC string);
初学SQL常遇到的问题点
使用Group by,那么Select的部分要么是分组项,要么就得是聚合函数。
Order by后面必须加Limit n。
Select表达式中不能用子查询,可以改写为Join。
Join不支持笛卡尔积,以及MapJoin的用法和使用场景。
Union all需要改成子查询的格式。
In/Not in语句对应的子查询只能有一列,而且返回的行数不能超过1000,否则也需要改成Join。
为了避免数据量太大的情况下导致 常遇问题点 中的第6点,您需要使用Join 进行改写。如下所示:
试用
SELECT d.*
FROM dept d
JOIN (
SELECT DISTINCT deptno AS no
FROM emp
) e
ON d.deptno = e.no;
MapJoin的典型场景,如下所示:
试用
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;
非等值连接,如下所示:
试用
SELECT a.ename
, b.ename
FROM emp a
LEFT OUTER JOIN emp b
ON b.empno = a.mgr;
Having 的用法,如下所示:
试用
SELECT emp.`JOB`
, MIN(emp.sal) AS sal
FROM `emp`
GROUP BY emp.`JOB`
HAVING MIN(emp.sal) > 1500;
时间处理上有很多好用的内建函数,如下所示:
试用
SELECT COUNT(empno) AS cnt_emp
, ROUND(AVG(sal), 2) AS avg_sal
, ROUND(AVG(datediff(getdate(), hiredate, 'dd')), 2) AS avg_hire
FROM `emp`
GROUP BY `DEPTNO`;
SQL 语句如下所示:
试用
SELECT *
FROM (
SELECT deptno
, ename
, sal
, ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY sal DESC) AS nums
FROM emp
) emp1
WHERE emp1.nums < 4;
SQL语句如下所示:
试用
SELECT deptno
, COUNT(empno) AS cnt
, ROUND(SUM(CASE
WHEN job = 'CLERK' THEN 1
ELSE 0
END) / COUNT(empno), 2) AS rate
FROM `EMP`
GROUP BY deptno;
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图::
项目 | Value | 数量 |
---|---|---|
电脑 | $1600 | 1 |
手机 | $12 | 1 |
导管 | $1 | 1 |
Markdown将文本转换为 HTML。
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分