本文為您介紹MaxCompute SQL常見使用場景,讓您快速掌握SQL的寫法。
準備數據集
本文以emp表和dept表為示例數據集。您可以自行在MaxCompute項目上創建表并上傳數據。具體如下:
創建表。
創建emp表
CREATE TABLE IF NOT EXISTS emp ( EMPNO STRING, ENAME STRING, JOB STRING, MGR BIGINT, HIREDATE DATETIME, SAL DOUBLE, COMM DOUBLE, DEPTNO BIGINT);
創建dept表
CREATE TABLE IF NOT EXISTS dept ( DEPTNO BIGINT, DNAME STRING, LOC STRING);
進行數據導入,詳情請參見數據傳輸服務(上傳)場景與工具。
SQL示例
示例1:查詢員工人數大于零的所有部門。
為了避免數據量太大,此場景下建議您使用JOIN子句。
SELECT d.* FROM dept d JOIN ( SELECT DISTINCT deptno AS no FROM emp ) e ON d.deptno = e.no;
返回結果:
+------------+------------+------------+ | deptno | dname | loc | +------------+------------+------------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | +------------+------------+------------+
示例2:查詢薪金比SMITH高的所有員工。
此場景為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;
返回結果:
+------------+------------+------------+ | empno | ename | sal | +------------+------------+------------+ | 7499 | ALLEN | 1600.0 | | 7521 | WARD | 1250.0 | | 7566 | JONES | 2975.0 | | 7654 | MARTIN | 1250.0 | | 7698 | BLAKE | 2850.0 | | 7782 | CLARK | 2450.0 | | 7788 | SCOTT | 3000.0 | | 7839 | KING | 5000.0 | | 7844 | TURNER | 1500.0 | | 7876 | ADAMS | 1100.0 | | 7900 | JAMES | 950.0 | | 7902 | FORD | 3000.0 | | 7934 | MILLER | 1300.0 | +------------+------------+------------+
示例3:查詢所有員工的姓名及其直接上級的姓名。
此場景為等值連接。
SELECT a.ename , b.ename FROM emp a LEFT OUTER JOIN emp b ON b.empno = a.mgr;
返回結果:
+------------+------------+ | ename | ename2 | +------------+------------+ | SMITH | FORD | | ALLEN | BLAKE | | WARD | BLAKE | | JONES | KING | | MARTIN | BLAKE | | BLAKE | KING | | CLARK | KING | | SCOTT | JONES | | KING | NULL | | TURNER | BLAKE | | ADAMS | SCOTT | | JAMES | BLAKE | | FORD | JONES | | MILLER | CLARK | +------------+------------+
示例4:查詢基本薪金大于1500的所有工作。
此場景下需要使用HAVING子句。
SELECT emp.`JOB` , MIN(emp.sal) AS sal FROM `emp` GROUP BY emp.`JOB` HAVING MIN(emp.sal) > 1500;
返回結果:
+------------+------------+ | job | sal | +------------+------------+ | MANAGER | 2450.0 | | ANALYST | 3000.0 | | PRESIDENT | 5000.0 | +------------+------------+
示例5:查詢在每個部門工作的員工數量、平均工資和平均服務期限。
此場景為使用內建函數的典型場景。
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`;
返回結果:
+------------+------------+------------+ | cnt_emp | avg_sal | avg_hire | +------------+------------+------------+ | 5 | 2175.0 | 14886.2 | | 6 | 1566.67 | 15715.33 | | 3 | 2916.67 | 15606.33 | +------------+------------+------------+
示例6:查詢每個部門的薪水前3名的人員的姓名以及其排序。
此場景為典型的Top N場景。
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;
返回結果:
+------------+------------+------------+------------+ | deptno | ename | sal | nums | +------------+------------+------------+------------+ | 10 | KING | 5000.0 | 1 | | 10 | CLARK | 2450.0 | 2 | | 10 | MILLER | 1300.0 | 3 | | 20 | SCOTT | 3000.0 | 1 | | 20 | FORD | 3000.0 | 2 | | 20 | JONES | 2975.0 | 3 | | 30 | BLAKE | 2850.0 | 1 | | 30 | ALLEN | 1600.0 | 2 | | 30 | TURNER | 1500.0 | 3 | +------------+------------+------------+------------+
示例7:查詢每個部門的人數以及該部門中辦事員(CLERK)人數的占比。
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;
返回結果:
+------------+------------+------------+ | deptno | cnt | rate | +------------+------------+------------+ | 20 | 5 | 0.4 | | 30 | 6 | 0.17 | | 10 | 3 | 0.33 | +------------+------------+------------+
注意事項
使用GROUP BY時,SELECT部分必須是分組項或聚合函數。
ORDER BY后面必須加LIMIT N。
SELECT表達式中不能用子查詢,可以改寫為JOIN。
JOIN不支持笛卡爾積,可以使用MAPJOIN替代。
UNION All需要改成子查詢的格式。
IN/NOT IN語句對應的子查詢只能有一列,而且返回的行數不能超過1000,否則也需要改成JOIN操作執行。
文檔內容是否對您有幫助?